clang-format: Apply formatting

Code submissions have continually suffered from formatting
inconsistencies that constantly have to be addressed.  Using
clang-format simplifies this by making code formatting more consistent,
and allows automation of the code formatting so that maintainers can
focus more on the code itself instead of code formatting.
master
jp9000 2019-06-22 22:13:45 -07:00
parent 53615ee10f
commit f53df7da64
567 changed files with 34068 additions and 32903 deletions

View File

@ -26,34 +26,34 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
uint32_t flags = obs_source_get_flags(source);
uint32_t mixers = obs_source_get_audio_mixers(source);
forceMonoContainer = new QWidget();
mixerContainer = new QWidget();
balanceContainer = new QWidget();
labelL = new QLabel();
labelR = new QLabel();
nameLabel = new QLabel();
volume = new QDoubleSpinBox();
forceMono = new QCheckBox();
balance = new BalanceSlider();
forceMonoContainer = new QWidget();
mixerContainer = new QWidget();
balanceContainer = new QWidget();
labelL = new QLabel();
labelR = new QLabel();
nameLabel = new QLabel();
volume = new QDoubleSpinBox();
forceMono = new QCheckBox();
balance = new BalanceSlider();
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
monitoringType = new QComboBox();
monitoringType = new QComboBox();
#endif
syncOffset = new QSpinBox();
mixer1 = new QCheckBox();
mixer2 = new QCheckBox();
mixer3 = new QCheckBox();
mixer4 = new QCheckBox();
mixer5 = new QCheckBox();
mixer6 = new QCheckBox();
syncOffset = new QSpinBox();
mixer1 = new QCheckBox();
mixer2 = new QCheckBox();
mixer3 = new QCheckBox();
mixer4 = new QCheckBox();
mixer5 = new QCheckBox();
mixer6 = new QCheckBox();
volChangedSignal.Connect(handler, "volume", OBSSourceVolumeChanged,
this);
this);
syncOffsetSignal.Connect(handler, "audio_sync", OBSSourceSyncChanged,
this);
this);
flagsSignal.Connect(handler, "update_flags", OBSSourceFlagsChanged,
this);
this);
mixersSignal.Connect(handler, "audio_mixers", OBSSourceMixersChanged,
this);
this);
hlayout = new QHBoxLayout();
hlayout->setContentsMargins(0, 0, 0, 0);
@ -87,8 +87,8 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
forceMono->setChecked((flags & OBS_SOURCE_FLAG_FORCE_MONO) != 0);
forceMonoContainer->layout()->addWidget(forceMono);
forceMonoContainer->layout()->setAlignment(forceMono,
Qt::AlignHCenter | Qt::AlignVCenter);
forceMonoContainer->layout()->setAlignment(
forceMono, Qt::AlignHCenter | Qt::AlignVCenter);
balance->setOrientation(Qt::Horizontal);
balance->setMinimum(0);
@ -96,10 +96,10 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
balance->setTickPosition(QSlider::TicksAbove);
balance->setTickInterval(50);
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
const char *speakers = config_get_string(main->Config(), "Audio",
"ChannelSetup");
const char *speakers =
config_get_string(main->Config(), "Audio", "ChannelSetup");
if (strcmp(speakers, "Mono") == 0)
balance->setEnabled(false);
@ -117,31 +117,31 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
int idx;
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.None"),
(int)OBS_MONITORING_TYPE_NONE);
(int)OBS_MONITORING_TYPE_NONE);
monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.MonitorOnly"),
(int)OBS_MONITORING_TYPE_MONITOR_ONLY);
(int)OBS_MONITORING_TYPE_MONITOR_ONLY);
monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.Both"),
(int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT);
(int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT);
int mt = (int)obs_source_get_monitoring_type(source);
idx = monitoringType->findData(mt);
monitoringType->setCurrentIndex(idx);
#endif
mixer1->setText("1");
mixer1->setChecked(mixers & (1<<0));
mixer1->setChecked(mixers & (1 << 0));
mixer2->setText("2");
mixer2->setChecked(mixers & (1<<1));
mixer2->setChecked(mixers & (1 << 1));
mixer3->setText("3");
mixer3->setChecked(mixers & (1<<2));
mixer3->setChecked(mixers & (1 << 2));
mixer4->setText("4");
mixer4->setChecked(mixers & (1<<3));
mixer4->setChecked(mixers & (1 << 3));
mixer5->setText("5");
mixer5->setChecked(mixers & (1<<4));
mixer5->setChecked(mixers & (1 << 4));
mixer6->setText("6");
mixer6->setChecked(mixers & (1<<5));
mixer6->setChecked(mixers & (1 << 5));
speaker_layout sl = obs_source_get_speaker_layout(source);
if (sl == SPEAKERS_STEREO) {
balanceContainer->layout()->addWidget(labelL);
balanceContainer->layout()->addWidget(balance);
@ -156,32 +156,32 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
mixerContainer->layout()->addWidget(mixer5);
mixerContainer->layout()->addWidget(mixer6);
QWidget::connect(volume, SIGNAL(valueChanged(double)),
this, SLOT(volumeChanged(double)));
QWidget::connect(forceMono, SIGNAL(clicked(bool)),
this, SLOT(downmixMonoChanged(bool)));
QWidget::connect(balance, SIGNAL(valueChanged(int)),
this, SLOT(balanceChanged(int)));
QWidget::connect(balance, SIGNAL(doubleClicked()),
this, SLOT(ResetBalance()));
QWidget::connect(syncOffset, SIGNAL(valueChanged(int)),
this, SLOT(syncOffsetChanged(int)));
QWidget::connect(volume, SIGNAL(valueChanged(double)), this,
SLOT(volumeChanged(double)));
QWidget::connect(forceMono, SIGNAL(clicked(bool)), this,
SLOT(downmixMonoChanged(bool)));
QWidget::connect(balance, SIGNAL(valueChanged(int)), this,
SLOT(balanceChanged(int)));
QWidget::connect(balance, SIGNAL(doubleClicked()), this,
SLOT(ResetBalance()));
QWidget::connect(syncOffset, SIGNAL(valueChanged(int)), this,
SLOT(syncOffsetChanged(int)));
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)),
this, SLOT(monitoringTypeChanged(int)));
QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)), this,
SLOT(monitoringTypeChanged(int)));
#endif
QWidget::connect(mixer1, SIGNAL(clicked(bool)),
this, SLOT(mixer1Changed(bool)));
QWidget::connect(mixer2, SIGNAL(clicked(bool)),
this, SLOT(mixer2Changed(bool)));
QWidget::connect(mixer3, SIGNAL(clicked(bool)),
this, SLOT(mixer3Changed(bool)));
QWidget::connect(mixer4, SIGNAL(clicked(bool)),
this, SLOT(mixer4Changed(bool)));
QWidget::connect(mixer5, SIGNAL(clicked(bool)),
this, SLOT(mixer5Changed(bool)));
QWidget::connect(mixer6, SIGNAL(clicked(bool)),
this, SLOT(mixer6Changed(bool)));
QWidget::connect(mixer1, SIGNAL(clicked(bool)), this,
SLOT(mixer1Changed(bool)));
QWidget::connect(mixer2, SIGNAL(clicked(bool)), this,
SLOT(mixer2Changed(bool)));
QWidget::connect(mixer3, SIGNAL(clicked(bool)), this,
SLOT(mixer3Changed(bool)));
QWidget::connect(mixer4, SIGNAL(clicked(bool)), this,
SLOT(mixer4Changed(bool)));
QWidget::connect(mixer5, SIGNAL(clicked(bool)), this,
SLOT(mixer5Changed(bool)));
QWidget::connect(mixer6, SIGNAL(clicked(bool)), this,
SLOT(mixer6Changed(bool)));
setObjectName(sourceName);
}
@ -214,7 +214,7 @@ void OBSAdvAudioCtrl::ShowAudioControl(QGridLayout *layout)
#endif
layout->addWidget(mixerContainer, lastRow, idx++);
layout->layout()->setAlignment(mixerContainer,
Qt::AlignHCenter | Qt::AlignVCenter);
Qt::AlignHCenter | Qt::AlignVCenter);
}
/* ------------------------------------------------------------------------- */
@ -223,30 +223,30 @@ void OBSAdvAudioCtrl::ShowAudioControl(QGridLayout *layout)
void OBSAdvAudioCtrl::OBSSourceFlagsChanged(void *param, calldata_t *calldata)
{
uint32_t flags = (uint32_t)calldata_int(calldata, "flags");
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl*>(param),
"SourceFlagsChanged", Q_ARG(uint32_t, flags));
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl *>(param),
"SourceFlagsChanged", Q_ARG(uint32_t, flags));
}
void OBSAdvAudioCtrl::OBSSourceVolumeChanged(void *param, calldata_t *calldata)
{
float volume = (float)calldata_float(calldata, "volume");
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl*>(param),
"SourceVolumeChanged", Q_ARG(float, volume));
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl *>(param),
"SourceVolumeChanged", Q_ARG(float, volume));
}
void OBSAdvAudioCtrl::OBSSourceSyncChanged(void *param, calldata_t *calldata)
{
int64_t offset = calldata_int(calldata, "offset");
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl*>(param),
"SourceSyncChanged", Q_ARG(int64_t, offset));
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl *>(param),
"SourceSyncChanged", Q_ARG(int64_t, offset));
}
void OBSAdvAudioCtrl::OBSSourceMixersChanged(void *param, calldata_t *calldata)
{
uint32_t mixers = (uint32_t)calldata_int(calldata, "mixers");
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl*>(param),
"SourceMixersChanged", Q_ARG(uint32_t, mixers));
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl *>(param),
"SourceMixersChanged",
Q_ARG(uint32_t, mixers));
}
/* ------------------------------------------------------------------------- */
@ -279,12 +279,12 @@ void OBSAdvAudioCtrl::SourceSyncChanged(int64_t offset)
void OBSAdvAudioCtrl::SourceMixersChanged(uint32_t mixers)
{
setCheckboxState(mixer1, mixers & (1<<0));
setCheckboxState(mixer2, mixers & (1<<1));
setCheckboxState(mixer3, mixers & (1<<2));
setCheckboxState(mixer4, mixers & (1<<3));
setCheckboxState(mixer5, mixers & (1<<4));
setCheckboxState(mixer6, mixers & (1<<5));
setCheckboxState(mixer1, mixers & (1 << 0));
setCheckboxState(mixer2, mixers & (1 << 1));
setCheckboxState(mixer3, mixers & (1 << 2));
setCheckboxState(mixer4, mixers & (1 << 3));
setCheckboxState(mixer5, mixers & (1 << 4));
setCheckboxState(mixer6, mixers & (1 << 5));
}
/* ------------------------------------------------------------------------- */
@ -335,14 +335,13 @@ void OBSAdvAudioCtrl::ResetBalance()
balance->setValue(50);
}
void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds)
{
int64_t cur_val = obs_source_get_sync_offset(source);
if (cur_val / NSEC_PER_MSEC != milliseconds)
obs_source_set_sync_offset(source,
int64_t(milliseconds) * NSEC_PER_MSEC);
obs_source_set_sync_offset(source, int64_t(milliseconds) *
NSEC_PER_MSEC);
}
void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
@ -365,17 +364,19 @@ void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
}
blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s",
obs_source_get_name(source), type);
obs_source_get_name(source), type);
}
static inline void setMixer(obs_source_t *source, const int mixerIdx,
const bool checked)
const bool checked)
{
uint32_t mixers = obs_source_get_audio_mixers(source);
uint32_t new_mixers = mixers;
if (checked) new_mixers |= (1<<mixerIdx);
else new_mixers &= ~(1<<mixerIdx);
if (checked)
new_mixers |= (1 << mixerIdx);
else
new_mixers &= ~(1 << mixerIdx);
obs_source_set_audio_mixers(source, new_mixers);
}

View File

@ -16,31 +16,31 @@ class OBSAdvAudioCtrl : public QObject {
Q_OBJECT
private:
OBSSource source;
OBSSource source;
QPointer<QWidget> forceMonoContainer;
QPointer<QWidget> mixerContainer;
QPointer<QWidget> balanceContainer;
QPointer<QWidget> forceMonoContainer;
QPointer<QWidget> mixerContainer;
QPointer<QWidget> balanceContainer;
QPointer<QLabel> nameLabel;
QPointer<QLabel> nameLabel;
QPointer<QDoubleSpinBox> volume;
QPointer<QCheckBox> forceMono;
QPointer<BalanceSlider>balance;
QPointer<QLabel> labelL;
QPointer<QLabel> labelR;
QPointer<QSpinBox> syncOffset;
QPointer<QComboBox> monitoringType;
QPointer<QCheckBox> mixer1;
QPointer<QCheckBox> mixer2;
QPointer<QCheckBox> mixer3;
QPointer<QCheckBox> mixer4;
QPointer<QCheckBox> mixer5;
QPointer<QCheckBox> mixer6;
QPointer<QCheckBox> forceMono;
QPointer<BalanceSlider> balance;
QPointer<QLabel> labelL;
QPointer<QLabel> labelR;
QPointer<QSpinBox> syncOffset;
QPointer<QComboBox> monitoringType;
QPointer<QCheckBox> mixer1;
QPointer<QCheckBox> mixer2;
QPointer<QCheckBox> mixer3;
QPointer<QCheckBox> mixer4;
QPointer<QCheckBox> mixer5;
QPointer<QCheckBox> mixer6;
OBSSignal volChangedSignal;
OBSSignal syncOffsetSignal;
OBSSignal flagsSignal;
OBSSignal mixersSignal;
OBSSignal volChangedSignal;
OBSSignal syncOffsetSignal;
OBSSignal flagsSignal;
OBSSignal mixersSignal;
static void OBSSourceFlagsChanged(void *param, calldata_t *calldata);
static void OBSSourceVolumeChanged(void *param, calldata_t *calldata);
@ -51,7 +51,7 @@ public:
OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_);
virtual ~OBSAdvAudioCtrl();
inline obs_source_t *GetSource() const {return source;}
inline obs_source_t *GetSource() const { return source; }
void ShowAudioControl(QGridLayout *layout);
public slots:

View File

@ -11,14 +11,13 @@ using namespace std;
Q_DECLARE_METATYPE(OBSScene);
Q_DECLARE_METATYPE(OBSSource);
template <typename T>
static T GetOBSRef(QListWidgetItem *item)
template<typename T> static T GetOBSRef(QListWidgetItem *item)
{
return item->data(static_cast<int>(QtDataRole::OBSRef)).value<T>();
}
void EnumProfiles(function<bool (const char *, const char *)> &&cb);
void EnumSceneCollections(function<bool (const char *, const char *)> &&cb);
void EnumProfiles(function<bool(const char *, const char *)> &&cb);
void EnumSceneCollections(function<bool(const char *, const char *)> &&cb);
extern volatile bool streaming_active;
extern volatile bool recording_active;
@ -30,18 +29,18 @@ template<typename T> struct OBSStudioCallback {
T callback;
void *private_data;
inline OBSStudioCallback(T cb, void *p) :
callback(cb), private_data(p)
{}
inline OBSStudioCallback(T cb, void *p) : callback(cb), private_data(p)
{
}
};
template <typename T> inline size_t GetCallbackIdx(
vector<OBSStudioCallback<T>> &callbacks,
T callback, void *private_data)
template<typename T>
inline size_t GetCallbackIdx(vector<OBSStudioCallback<T>> &callbacks,
T callback, void *private_data)
{
for (size_t i = 0; i < callbacks.size(); i++) {
OBSStudioCallback<T> curCB = callbacks[i];
if (curCB.callback == callback &&
if (curCB.callback == callback &&
curCB.private_data == private_data)
return i;
}
@ -59,21 +58,21 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void *obs_frontend_get_main_window(void) override
{
return (void*)main;
return (void *)main;
}
void *obs_frontend_get_main_window_handle(void) override
{
return (void*)main->winId();
return (void *)main->winId();
}
void *obs_frontend_get_system_tray(void) override
{
return (void*)main->trayIcon.data();
return (void *)main->trayIcon.data();
}
void obs_frontend_get_scenes(
struct obs_frontend_source_list *sources) override
struct obs_frontend_source_list *sources) override
{
for (int i = 0; i < main->ui->scenes->count(); i++) {
QListWidgetItem *item = main->ui->scenes->item(i);
@ -101,23 +100,23 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void obs_frontend_set_current_scene(obs_source_t *scene) override
{
if (main->IsPreviewProgramMode()) {
QMetaObject::invokeMethod(main, "TransitionToScene",
WaitConnection(),
Q_ARG(OBSSource, OBSSource(scene)));
QMetaObject::invokeMethod(
main, "TransitionToScene", WaitConnection(),
Q_ARG(OBSSource, OBSSource(scene)));
} else {
QMetaObject::invokeMethod(main, "SetCurrentScene",
WaitConnection(),
Q_ARG(OBSSource, OBSSource(scene)),
Q_ARG(bool, false));
QMetaObject::invokeMethod(
main, "SetCurrentScene", WaitConnection(),
Q_ARG(OBSSource, OBSSource(scene)),
Q_ARG(bool, false));
}
}
void obs_frontend_get_transitions(
struct obs_frontend_source_list *sources) override
struct obs_frontend_source_list *sources) override
{
for (int i = 0; i < main->ui->transitions->count(); i++) {
OBSSource tr = main->ui->transitions->itemData(i)
.value<OBSSource>();
.value<OBSSource>();
obs_source_addref(tr);
da_push_back(sources->sources, &tr);
@ -132,11 +131,12 @@ struct OBSStudioAPI : obs_frontend_callbacks {
return tr;
}
void obs_frontend_set_current_transition(
obs_source_t *transition) override
void
obs_frontend_set_current_transition(obs_source_t *transition) override
{
QMetaObject::invokeMethod(main, "SetTransition",
Q_ARG(OBSSource, OBSSource(transition)));
Q_ARG(OBSSource,
OBSSource(transition)));
}
int obs_frontend_get_transition_duration(void) override
@ -146,15 +146,14 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void obs_frontend_set_transition_duration(int duration) override
{
QMetaObject::invokeMethod(main->ui->transitionDuration, "setValue",
Q_ARG(int, duration));
QMetaObject::invokeMethod(main->ui->transitionDuration,
"setValue", Q_ARG(int, duration));
}
void obs_frontend_get_scene_collections(
std::vector<std::string> &strings) override
std::vector<std::string> &strings) override
{
auto addCollection = [&](const char *name, const char *)
{
auto addCollection = [&](const char *name, const char *) {
strings.emplace_back(name);
return true;
};
@ -164,15 +163,15 @@ struct OBSStudioAPI : obs_frontend_callbacks {
char *obs_frontend_get_current_scene_collection(void) override
{
const char *cur_name = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
const char *cur_name = config_get_string(
App()->GlobalConfig(), "Basic", "SceneCollection");
return bstrdup(cur_name);
}
void obs_frontend_set_current_scene_collection(
const char *collection) override
const char *collection) override
{
QList<QAction*> menuActions =
QList<QAction *> menuActions =
main->ui->sceneCollectionMenu->actions();
QString qstrCollection = QT_UTF8(collection);
@ -189,24 +188,21 @@ struct OBSStudioAPI : obs_frontend_callbacks {
}
}
bool obs_frontend_add_scene_collection(
const char *name) override
bool obs_frontend_add_scene_collection(const char *name) override
{
bool success = false;
QMetaObject::invokeMethod(main,
"AddSceneCollection",
WaitConnection(),
Q_RETURN_ARG(bool, success),
Q_ARG(bool, true),
Q_ARG(QString, QT_UTF8(name)));
QMetaObject::invokeMethod(main, "AddSceneCollection",
WaitConnection(),
Q_RETURN_ARG(bool, success),
Q_ARG(bool, true),
Q_ARG(QString, QT_UTF8(name)));
return success;
}
void obs_frontend_get_profiles(
std::vector<std::string> &strings) override
void
obs_frontend_get_profiles(std::vector<std::string> &strings) override
{
auto addProfile = [&](const char *name, const char *)
{
auto addProfile = [&](const char *name, const char *) {
strings.emplace_back(name);
return true;
};
@ -217,14 +213,13 @@ struct OBSStudioAPI : obs_frontend_callbacks {
char *obs_frontend_get_current_profile(void) override
{
const char *name = config_get_string(App()->GlobalConfig(),
"Basic", "Profile");
"Basic", "Profile");
return bstrdup(name);
}
void obs_frontend_set_current_profile(const char *profile) override
{
QList<QAction*> menuActions =
main->ui->profileMenu->actions();
QList<QAction *> menuActions = main->ui->profileMenu->actions();
QString qstrProfile = QT_UTF8(profile);
for (int i = 0; i < menuActions.count(); i++) {
@ -293,16 +288,16 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void *obs_frontend_add_tools_menu_qaction(const char *name) override
{
main->ui->menuTools->setEnabled(true);
return (void*)main->ui->menuTools->addAction(QT_UTF8(name));
return (void *)main->ui->menuTools->addAction(QT_UTF8(name));
}
void obs_frontend_add_tools_menu_item(const char *name,
obs_frontend_cb callback, void *private_data) override
obs_frontend_cb callback,
void *private_data) override
{
main->ui->menuTools->setEnabled(true);
auto func = [private_data, callback] ()
{
auto func = [private_data, callback]() {
callback(private_data);
};
@ -312,11 +307,11 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void *obs_frontend_add_dock(void *dock) override
{
return (void*)main->AddDockWidget((QDockWidget *)dock);
return (void *)main->AddDockWidget((QDockWidget *)dock);
}
void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(callbacks, callback, private_data);
if (idx == (size_t)-1)
@ -324,7 +319,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
}
void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(callbacks, callback, private_data);
if (idx == (size_t)-1)
@ -364,10 +359,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
return App()->GlobalConfig();
}
void obs_frontend_save(void) override
{
main->SaveProject();
}
void obs_frontend_save(void) override { main->SaveProject(); }
void obs_frontend_defer_save_begin(void) override
{
@ -380,19 +372,19 @@ struct OBSStudioAPI : obs_frontend_callbacks {
}
void obs_frontend_add_save_callback(obs_frontend_save_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(saveCallbacks, callback,
private_data);
size_t idx =
GetCallbackIdx(saveCallbacks, callback, private_data);
if (idx == (size_t)-1)
saveCallbacks.emplace_back(callback, private_data);
}
void obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(saveCallbacks, callback,
private_data);
size_t idx =
GetCallbackIdx(saveCallbacks, callback, private_data);
if (idx == (size_t)-1)
return;
@ -400,19 +392,19 @@ struct OBSStudioAPI : obs_frontend_callbacks {
}
void obs_frontend_add_preload_callback(obs_frontend_save_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(preloadCallbacks, callback,
private_data);
private_data);
if (idx == (size_t)-1)
preloadCallbacks.emplace_back(callback, private_data);
}
void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(preloadCallbacks, callback,
private_data);
private_data);
if (idx == (size_t)-1)
return;
@ -420,7 +412,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
}
void obs_frontend_push_ui_translation(
obs_frontend_translate_ui_cb translate) override
obs_frontend_translate_ui_cb translate) override
{
App()->PushUITranslation(translate);
}
@ -483,12 +475,14 @@ struct OBSStudioAPI : obs_frontend_callbacks {
return source;
}
void obs_frontend_set_current_preview_scene(obs_source_t *scene) override
void
obs_frontend_set_current_preview_scene(obs_source_t *scene) override
{
if (main->IsPreviewProgramMode()) {
QMetaObject::invokeMethod(main, "SetCurrentScene",
Q_ARG(OBSSource, OBSSource(scene)),
Q_ARG(bool, false));
Q_ARG(OBSSource,
OBSSource(scene)),
Q_ARG(bool, false));
}
}

View File

@ -32,7 +32,7 @@ static const char *EncoderName(const char *id)
return NullToEmpty(obs_encoder_get_display_name(id));
}
static map<int, const char*> bitrateMap;
static map<int, const char *> bitrateMap;
static once_flag populateBitrateMap;
static void HandleIntProperty(obs_property_t *prop, const char *id)
@ -48,10 +48,11 @@ static void HandleListProperty(obs_property_t *prop, const char *id)
{
obs_combo_format format = obs_property_list_format(prop);
if (format != OBS_COMBO_FORMAT_INT) {
blog(LOG_ERROR, "Encoder '%s' (%s) returned bitrate "
"OBS_PROPERTY_LIST property of unhandled "
"format %d",
EncoderName(id), id, static_cast<int>(format));
blog(LOG_ERROR,
"Encoder '%s' (%s) returned bitrate "
"OBS_PROPERTY_LIST property of unhandled "
"format %d",
EncoderName(id), id, static_cast<int>(format));
return;
}
@ -60,38 +61,35 @@ static void HandleListProperty(obs_property_t *prop, const char *id)
if (obs_property_list_item_disabled(prop, i))
continue;
int bitrate = static_cast<int>(
obs_property_list_item_int(prop, i));
int bitrate =
static_cast<int>(obs_property_list_item_int(prop, i));
bitrateMap[bitrate] = id;
}
}
static void HandleSampleRate(obs_property_t* prop, const char *id)
static void HandleSampleRate(obs_property_t *prop, const char *id)
{
auto ReleaseData = [](obs_data_t *data)
{
obs_data_release(data);
};
auto ReleaseData = [](obs_data_t *data) { obs_data_release(data); };
std::unique_ptr<obs_data_t, decltype(ReleaseData)> data{
obs_encoder_defaults(id),
ReleaseData};
obs_encoder_defaults(id), ReleaseData};
if (!data) {
blog(LOG_ERROR, "Failed to get defaults for encoder '%s' (%s) "
"while populating bitrate map",
EncoderName(id), id);
blog(LOG_ERROR,
"Failed to get defaults for encoder '%s' (%s) "
"while populating bitrate map",
EncoderName(id), id);
return;
}
auto main = reinterpret_cast<OBSMainWindow*>(App()->GetMainWindow());
auto main = reinterpret_cast<OBSMainWindow *>(App()->GetMainWindow());
if (!main) {
blog(LOG_ERROR, "Failed to get main window while populating "
"bitrate map");
return;
}
uint32_t sampleRate = config_get_uint(main->Config(), "Audio",
"SampleRate");
uint32_t sampleRate =
config_get_uint(main->Config(), "Audio", "SampleRate");
obs_data_set_int(data.get(), "samplerate", sampleRate);
@ -100,23 +98,22 @@ static void HandleSampleRate(obs_property_t* prop, const char *id)
static void HandleEncoderProperties(const char *id)
{
auto DestroyProperties = [](obs_properties_t *props)
{
auto DestroyProperties = [](obs_properties_t *props) {
obs_properties_destroy(props);
};
std::unique_ptr<obs_properties_t, decltype(DestroyProperties)> props{
obs_get_encoder_properties(id),
DestroyProperties};
obs_get_encoder_properties(id), DestroyProperties};
if (!props) {
blog(LOG_ERROR, "Failed to get properties for encoder "
"'%s' (%s)",
EncoderName(id), id);
blog(LOG_ERROR,
"Failed to get properties for encoder "
"'%s' (%s)",
EncoderName(id), id);
return;
}
obs_property_t *samplerate = obs_properties_get(props.get(),
"samplerate");
obs_property_t *samplerate =
obs_properties_get(props.get(), "samplerate");
if (samplerate)
HandleSampleRate(samplerate, id);
@ -130,12 +127,14 @@ static void HandleEncoderProperties(const char *id)
case OBS_PROPERTY_LIST:
return HandleListProperty(bitrate, id);
default: break;
default:
break;
}
blog(LOG_ERROR, "Encoder '%s' (%s) returned bitrate property "
"of unhandled type %d", EncoderName(id), id,
static_cast<int>(type));
blog(LOG_ERROR,
"Encoder '%s' (%s) returned bitrate property "
"of unhandled type %d",
EncoderName(id), id, static_cast<int>(type));
}
static const char *GetCodec(const char *id)
@ -146,8 +145,7 @@ static const char *GetCodec(const char *id)
static const string aac_ = "AAC";
static void PopulateBitrateMap()
{
call_once(populateBitrateMap, []()
{
call_once(populateBitrateMap, []() {
struct obs_audio_info aoi;
obs_get_audio_info(&aoi);
uint32_t output_channels = get_audio_channels(aoi.speakers);
@ -156,13 +154,12 @@ static void PopulateBitrateMap()
const char *id = nullptr;
for (size_t i = 0; obs_enum_encoder_types(i, &id); i++) {
auto Compare = [=](const string &val)
{
auto Compare = [=](const string &val) {
return val == NullToEmpty(id);
};
if (find_if(begin(encoders), end(encoders), Compare) !=
end(encoders))
end(encoders))
continue;
if (aac_ != GetCodec(id))
@ -198,11 +195,11 @@ static void PopulateBitrateMap()
<< entry.second << ')';
blog(LOG_DEBUG, "AAC encoder bitrate mapping:%s",
ss.str().c_str());
ss.str().c_str());
});
}
const map<int, const char*> &GetAACEncoderBitrateMap()
const map<int, const char *> &GetAACEncoderBitrateMap()
{
PopulateBitrateMap();
return bitrateMap;

View File

@ -4,6 +4,6 @@
#include <map>
const std::map<int, const char*> &GetAACEncoderBitrateMap();
const std::map<int, const char *> &GetAACEncoderBitrateMap();
const char *GetAACEncoderForBitrate(int bitrate);
int FindClosestAvailableAACBitrate(int bitrate);

View File

@ -43,7 +43,8 @@ void Auth::Load()
{
OBSBasic *main = OBSBasic::Get();
const char *typeStr = config_get_string(main->Config(), "Auth", "Type");
if (!typeStr) typeStr = "";
if (!typeStr)
typeStr = "";
main->auth = Create(typeStr);
if (main->auth) {

View File

@ -8,8 +8,8 @@ class Auth : public QObject {
Q_OBJECT
protected:
virtual void SaveInternal()=0;
virtual bool LoadInternal()=0;
virtual void SaveInternal() = 0;
virtual bool LoadInternal() = 0;
bool firstLoad = true;
@ -19,13 +19,14 @@ protected:
ErrorInfo(std::string message_, std::string error_)
: message(message_), error(error_)
{}
{
}
};
public:
enum class Type {
None,
OAuth_StreamKey
OAuth_StreamKey,
};
struct Def {
@ -33,13 +34,13 @@ public:
Type type;
};
typedef std::function<std::shared_ptr<Auth> ()> create_cb;
typedef std::function<std::shared_ptr<Auth>()> create_cb;
inline Auth(const Def &d) : def(d) {}
virtual ~Auth() {}
inline Type type() const {return def.type;}
inline const char *service() const {return def.service.c_str();}
inline Type type() const { return def.type; }
inline const char *service() const { return def.service.c_str(); }
virtual void LoadUI() {}

View File

@ -26,24 +26,16 @@ extern QCefCookieManager *panel_cookies;
/* ------------------------------------------------------------------------- */
#define MIXER_AUTH_URL \
"https://obsproject.com/app-auth/mixer?action=redirect"
#define MIXER_TOKEN_URL \
"https://obsproject.com/app-auth/mixer-token"
#define MIXER_AUTH_URL "https://obsproject.com/app-auth/mixer?action=redirect"
#define MIXER_TOKEN_URL "https://obsproject.com/app-auth/mixer-token"
#define MIXER_SCOPE_VERSION 1
static Auth::Def mixerDef = {
"Mixer",
Auth::Type::OAuth_StreamKey
};
static Auth::Def mixerDef = {"Mixer", Auth::Type::OAuth_StreamKey};
/* ------------------------------------------------------------------------- */
MixerAuth::MixerAuth(const Def &d)
: OAuthStreamKey(d)
{
}
MixerAuth::MixerAuth(const Def &d) : OAuthStreamKey(d) {}
bool MixerAuth::GetChannelInfo(bool allow_retry)
try {
@ -71,23 +63,16 @@ try {
bool success;
if (id.empty()) {
auto func = [&] () {
auto func = [&]() {
success = GetRemoteFile(
"https://mixer.com/api/v1/users/current",
output,
error,
nullptr,
"application/json",
nullptr,
headers,
nullptr,
5);
"https://mixer.com/api/v1/users/current",
output, error, nullptr, "application/json",
nullptr, headers, nullptr, 5);
};
ExecThreadedWithoutBlocking(
func,
QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
func, QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
if (!success || output.empty())
throw ErrorInfo("Failed to get user info from remote",
error);
@ -98,11 +83,12 @@ try {
error = json["error"].string_value();
if (!error.empty())
throw ErrorInfo(error,
json["error_description"].string_value());
throw ErrorInfo(
error,
json["error_description"].string_value());
id = std::to_string(json["channel"]["id"].int_value());
name = json["channel"]["token"].string_value();
id = std::to_string(json["channel"]["id"].int_value());
name = json["channel"]["token"].string_value();
}
/* ------------------ */
@ -114,23 +100,15 @@ try {
output.clear();
auto func = [&] () {
success = GetRemoteFile(
url.c_str(),
output,
error,
nullptr,
"application/json",
nullptr,
headers,
nullptr,
5);
auto func = [&]() {
success = GetRemoteFile(url.c_str(), output, error, nullptr,
"application/json", nullptr, headers,
nullptr, 5);
};
ExecThreadedWithoutBlocking(
func,
QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
func, QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
if (!success || output.empty())
throw ErrorInfo("Failed to get stream key from remote", error);
@ -140,7 +118,8 @@ try {
error = json["error"].string_value();
if (!error.empty())
throw ErrorInfo(error, json["error_description"].string_value());
throw ErrorInfo(error,
json["error_description"].string_value());
std::string key_suffix = json["streamKey"].string_value();
@ -161,14 +140,13 @@ try {
} catch (ErrorInfo info) {
QString title = QTStr("Auth.ChannelFailure.Title");
QString text = QTStr("Auth.ChannelFailure.Text")
.arg(service(), info.message.c_str(), info.error.c_str());
.arg(service(), info.message.c_str(),
info.error.c_str());
QMessageBox::warning(OBSBasic::Get(), title, text);
blog(LOG_WARNING, "%s: %s: %s",
__FUNCTION__,
info.message.c_str(),
info.error.c_str());
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
info.error.c_str());
return false;
}
@ -179,15 +157,13 @@ void MixerAuth::SaveInternal()
config_set_string(main->Config(), service(), "Id", id.c_str());
if (uiLoaded) {
config_set_string(main->Config(), service(), "DockState",
main->saveState().toBase64().constData());
main->saveState().toBase64().constData());
}
OAuthStreamKey::SaveInternal();
}
static inline std::string get_config_str(
OBSBasic *main,
const char *section,
const char *name)
static inline std::string get_config_str(OBSBasic *main, const char *section,
const char *name)
{
const char *val = config_get_string(main->Config(), section, name);
return val ? val : "";
@ -252,8 +228,8 @@ void MixerAuth::LoadUI()
if (firstLoad) {
chat->setVisible(true);
} else {
const char *dockStateStr = config_get_string(main->Config(),
service(), "DockState");
const char *dockStateStr = config_get_string(
main->Config(), service(), "DockState");
QByteArray dockState =
QByteArray::fromBase64(QByteArray(dockStateStr));
main->restoreState(dockState);
@ -301,7 +277,7 @@ std::shared_ptr<Auth> MixerAuth::Login(QWidget *parent)
deobfuscate_str(&client_id[0], MIXER_HASH);
if (!auth->GetToken(MIXER_TOKEN_URL, client_id, MIXER_SCOPE_VERSION,
QT_TO_UTF8(login.GetCode()))) {
QT_TO_UTF8(login.GetCode()))) {
return nullptr;
}
@ -328,9 +304,6 @@ static void DeleteCookies()
void RegisterMixerAuth()
{
OAuth::RegisterOAuth(
mixerDef,
CreateMixerAuth,
MixerAuth::Login,
DeleteCookies);
OAuth::RegisterOAuth(mixerDef, CreateMixerAuth, MixerAuth::Login,
DeleteCookies);
}

View File

@ -23,8 +23,7 @@ extern QCefCookieManager *panel_cookies;
/* ------------------------------------------------------------------------- */
OAuthLogin::OAuthLogin(QWidget *parent, const std::string &url, bool token)
: QDialog (parent),
get_token (token)
: QDialog(parent), get_token(token)
{
if (!cef) {
return;
@ -46,14 +45,13 @@ OAuthLogin::OAuthLogin(QWidget *parent, const std::string &url, bool token)
return;
}
connect(cefWidget, SIGNAL(titleChanged(const QString &)),
this, SLOT(setWindowTitle(const QString &)));
connect(cefWidget, SIGNAL(urlChanged(const QString &)),
this, SLOT(urlChanged(const QString &)));
connect(cefWidget, SIGNAL(titleChanged(const QString &)), this,
SLOT(setWindowTitle(const QString &)));
connect(cefWidget, SIGNAL(urlChanged(const QString &)), this,
SLOT(urlChanged(const QString &)));
QPushButton *close = new QPushButton(QTStr("Cancel"));
connect(close, &QAbstractButton::clicked,
this, &QDialog::reject);
connect(close, &QAbstractButton::clicked, this, &QDialog::reject);
QHBoxLayout *bottomLayout = new QHBoxLayout();
bottomLayout->addStretch();
@ -111,7 +109,7 @@ struct OAuthInfo {
static std::vector<OAuthInfo> loginCBs;
void OAuth::RegisterOAuth(const Def &d, create_cb create, login_cb login,
delete_cookies_cb delete_cookies)
delete_cookies_cb delete_cookies)
{
OAuthInfo info = {d, login, delete_cookies};
loginCBs.push_back(info);
@ -142,16 +140,14 @@ void OAuth::SaveInternal()
{
OBSBasic *main = OBSBasic::Get();
config_set_string(main->Config(), service(), "RefreshToken",
refresh_token.c_str());
refresh_token.c_str());
config_set_string(main->Config(), service(), "Token", token.c_str());
config_set_uint(main->Config(), service(), "ExpireTime", expire_time);
config_set_int(main->Config(), service(), "ScopeVer", currentScopeVer);
}
static inline std::string get_config_str(
OBSBasic *main,
const char *section,
const char *name)
static inline std::string get_config_str(OBSBasic *main, const char *section,
const char *name)
{
const char *val = config_get_string(main->Config(), section, name);
return val ? val : "";
@ -163,11 +159,9 @@ bool OAuth::LoadInternal()
refresh_token = get_config_str(main, service(), "RefreshToken");
token = get_config_str(main, service(), "Token");
expire_time = config_get_uint(main->Config(), service(), "ExpireTime");
currentScopeVer = (int)config_get_int(main->Config(), service(),
"ScopeVer");
return implicit
? !token.empty()
: !refresh_token.empty();
currentScopeVer =
(int)config_get_int(main->Config(), service(), "ScopeVer");
return implicit ? !token.empty() : !refresh_token.empty();
}
bool OAuth::TokenExpired()
@ -180,7 +174,7 @@ bool OAuth::TokenExpired()
}
bool OAuth::GetToken(const char *url, const std::string &client_id,
int scope_ver, const std::string &auth_code, bool retry)
int scope_ver, const std::string &auth_code, bool retry)
try {
std::string output;
std::string error;
@ -191,8 +185,8 @@ try {
return true;
} else {
QString title = QTStr("Auth.InvalidScope.Title");
QString text = QTStr("Auth.InvalidScope.Text")
.arg(service());
QString text =
QTStr("Auth.InvalidScope.Text").arg(service());
QMessageBox::warning(OBSBasic::Get(), title, text);
}
@ -216,23 +210,15 @@ try {
bool success = false;
auto func = [&] () {
success = GetRemoteFile(
url,
output,
error,
nullptr,
"application/x-www-form-urlencoded",
post_data.c_str(),
std::vector<std::string>(),
nullptr,
5);
auto func = [&]() {
success = GetRemoteFile(url, output, error, nullptr,
"application/x-www-form-urlencoded",
post_data.c_str(),
std::vector<std::string>(), nullptr, 5);
};
ExecThreadedWithoutBlocking(
func,
QTStr("Auth.Authing.Title"),
QTStr("Auth.Authing.Text").arg(service()));
ExecThreadedWithoutBlocking(func, QTStr("Auth.Authing.Title"),
QTStr("Auth.Authing.Text").arg(service()));
if (!success || output.empty())
throw ErrorInfo("Failed to get token from remote", error);
@ -250,13 +236,14 @@ try {
}
}
if (!error.empty())
throw ErrorInfo(error, json["error_description"].string_value());
throw ErrorInfo(error,
json["error_description"].string_value());
/* -------------------------- */
/* success! */
expire_time = (uint64_t)time(nullptr) + json["expires_in"].int_value();
token = json["access_token"].string_value();
token = json["access_token"].string_value();
if (token.empty())
throw ErrorInfo("Failed to get token from remote", error);
@ -264,7 +251,8 @@ try {
refresh_token = json["refresh_token"].string_value();
if (refresh_token.empty())
throw ErrorInfo("Failed to get refresh token from "
"remote", error);
"remote",
error);
currentScopeVer = scope_ver;
}
@ -275,15 +263,14 @@ try {
if (!retry) {
QString title = QTStr("Auth.AuthFailure.Title");
QString text = QTStr("Auth.AuthFailure.Text")
.arg(service(), info.message.c_str(), info.error.c_str());
.arg(service(), info.message.c_str(),
info.error.c_str());
QMessageBox::warning(OBSBasic::Get(), title, text);
}
blog(LOG_WARNING, "%s: %s: %s",
__FUNCTION__,
info.message.c_str(),
info.error.c_str());
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
info.error.c_str());
return false;
}
@ -301,7 +288,7 @@ void OAuthStreamKey::OnStreamConfig()
if (bwtest && strcmp(this->service(), "Twitch") == 0)
obs_data_set_string(settings, "key",
(key_ + "?bandwidthtest=true").c_str());
(key_ + "?bandwidthtest=true").c_str());
else
obs_data_set_string(settings, "key", key_.c_str());

View File

@ -20,8 +20,8 @@ public:
OAuthLogin(QWidget *parent, const std::string &url, bool token);
~OAuthLogin();
inline QString GetCode() const {return code;}
inline bool LoadFail() const {return fail;}
inline QString GetCode() const { return code; }
inline bool LoadFail() const { return fail; }
virtual int exec() override;
@ -35,15 +35,16 @@ class OAuth : public Auth {
public:
inline OAuth(const Def &d) : Auth(d) {}
typedef std::function<std::shared_ptr<Auth> (QWidget *)> login_cb;
typedef std::function<std::shared_ptr<Auth>(QWidget *)> login_cb;
typedef std::function<void()> delete_cookies_cb;
static std::shared_ptr<Auth> Login(QWidget *parent,
const std::string &service);
const std::string &service);
static void DeleteCookies(const std::string &service);
static void RegisterOAuth(const Def &d, create_cb create,
login_cb login, delete_cookies_cb delete_cookies);
login_cb login,
delete_cookies_cb delete_cookies);
protected:
std::string refresh_token;
@ -55,12 +56,12 @@ protected:
virtual void SaveInternal() override;
virtual bool LoadInternal() override;
virtual bool RetryLogin()=0;
virtual bool RetryLogin() = 0;
bool TokenExpired();
bool GetToken(const char *url, const std::string &client_id,
int scope_ver,
const std::string &auth_code = std::string(),
bool retry = false);
int scope_ver,
const std::string &auth_code = std::string(),
bool retry = false);
};
class OAuthStreamKey : public OAuth {
@ -72,7 +73,7 @@ protected:
public:
inline OAuthStreamKey(const Def &d) : OAuth(d) {}
inline const std::string &key() const {return key_;}
inline const std::string &key() const { return key_; }
virtual void OnStreamConfig() override;
};

View File

@ -22,23 +22,17 @@ extern QCefCookieManager *panel_cookies;
/* ------------------------------------------------------------------------- */
#define RESTREAM_AUTH_URL "https://obsproject.com/app-auth/restream?action=redirect"
#define RESTREAM_AUTH_URL \
"https://obsproject.com/app-auth/restream?action=redirect"
#define RESTREAM_TOKEN_URL "https://obsproject.com/app-auth/restream-token"
#define RESTREAM_STREAMKEY_URL "https://api.restream.io/v2/user/streamKey"
#define RESTREAM_SCOPE_VERSION 1
static Auth::Def restreamDef = {
"Restream",
Auth::Type::OAuth_StreamKey
};
static Auth::Def restreamDef = {"Restream", Auth::Type::OAuth_StreamKey};
/* ------------------------------------------------------------------------- */
RestreamAuth::RestreamAuth(const Def &d)
: OAuthStreamKey(d)
{
}
RestreamAuth::RestreamAuth(const Def &d) : OAuthStreamKey(d) {}
bool RestreamAuth::GetChannelInfo()
try {
@ -65,23 +59,15 @@ try {
Json json;
bool success;
auto func = [&] () {
success = GetRemoteFile(
RESTREAM_STREAMKEY_URL,
output,
error,
nullptr,
"application/json",
nullptr,
headers,
nullptr,
5);
auto func = [&]() {
success = GetRemoteFile(RESTREAM_STREAMKEY_URL, output, error,
nullptr, "application/json", nullptr,
headers, nullptr, 5);
};
ExecThreadedWithoutBlocking(
func,
QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
func, QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
if (!success || output.empty())
throw ErrorInfo("Failed to get stream key from remote", error);
@ -91,7 +77,8 @@ try {
error = json["error"].string_value();
if (!error.empty())
throw ErrorInfo(error, json["error_description"].string_value());
throw ErrorInfo(error,
json["error_description"].string_value());
key_ = json["streamKey"].string_value();
@ -99,14 +86,13 @@ try {
} catch (ErrorInfo info) {
QString title = QTStr("Auth.ChannelFailure.Title");
QString text = QTStr("Auth.ChannelFailure.Text")
.arg(service(), info.message.c_str(), info.error.c_str());
.arg(service(), info.message.c_str(),
info.error.c_str());
QMessageBox::warning(OBSBasic::Get(), title, text);
blog(LOG_WARNING, "%s: %s: %s",
__FUNCTION__,
info.message.c_str(),
info.error.c_str());
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
info.error.c_str());
return false;
}
@ -114,14 +100,12 @@ void RestreamAuth::SaveInternal()
{
OBSBasic *main = OBSBasic::Get();
config_set_string(main->Config(), service(), "DockState",
main->saveState().toBase64().constData());
main->saveState().toBase64().constData());
OAuthStreamKey::SaveInternal();
}
static inline std::string get_config_str(
OBSBasic *main,
const char *section,
const char *name)
static inline std::string get_config_str(OBSBasic *main, const char *section,
const char *name)
{
const char *val = config_get_string(main->Config(), section, name);
return val ? val : "";
@ -201,10 +185,9 @@ void RestreamAuth::LoadUI()
if (firstLoad) {
chat->setVisible(true);
info->setVisible(true);
}
else {
const char *dockStateStr = config_get_string(main->Config(),
service(), "DockState");
} else {
const char *dockStateStr = config_get_string(
main->Config(), service(), "DockState");
QByteArray dockState =
QByteArray::fromBase64(QByteArray(dockStateStr));
main->restoreState(dockState);
@ -227,8 +210,7 @@ bool RestreamAuth::RetryLogin()
std::string client_id = RESTREAM_CLIENTID;
deobfuscate_str(&client_id[0], RESTREAM_HASH);
return GetToken(RESTREAM_TOKEN_URL, client_id,
RESTREAM_SCOPE_VERSION,
return GetToken(RESTREAM_TOKEN_URL, client_id, RESTREAM_SCOPE_VERSION,
QT_TO_UTF8(login.GetCode()), true);
}
@ -248,8 +230,8 @@ std::shared_ptr<Auth> RestreamAuth::Login(QWidget *parent)
deobfuscate_str(&client_id[0], RESTREAM_HASH);
if (!auth->GetToken(RESTREAM_TOKEN_URL, client_id,
RESTREAM_SCOPE_VERSION,
QT_TO_UTF8(login.GetCode()))) {
RESTREAM_SCOPE_VERSION,
QT_TO_UTF8(login.GetCode()))) {
return nullptr;
}
@ -275,9 +257,6 @@ static void DeleteCookies()
void RegisterRestreamAuth()
{
OAuth::RegisterOAuth(
restreamDef,
CreateRestreamAuth,
RestreamAuth::Login,
DeleteCookies);
OAuth::RegisterOAuth(restreamDef, CreateRestreamAuth,
RestreamAuth::Login, DeleteCookies);
}

View File

@ -24,35 +24,28 @@ extern QCefCookieManager *panel_cookies;
/* ------------------------------------------------------------------------- */
#define TWITCH_AUTH_URL \
"https://obsproject.com/app-auth/twitch?action=redirect"
#define TWITCH_TOKEN_URL \
"https://obsproject.com/app-auth/twitch-token"
#define ACCEPT_HEADER \
"Accept: application/vnd.twitchtv.v5+json"
#define TWITCH_AUTH_URL "https://obsproject.com/app-auth/twitch?action=redirect"
#define TWITCH_TOKEN_URL "https://obsproject.com/app-auth/twitch-token"
#define ACCEPT_HEADER "Accept: application/vnd.twitchtv.v5+json"
#define TWITCH_SCOPE_VERSION 1
static Auth::Def twitchDef = {
"Twitch",
Auth::Type::OAuth_StreamKey
};
static Auth::Def twitchDef = {"Twitch", Auth::Type::OAuth_StreamKey};
/* ------------------------------------------------------------------------- */
TwitchAuth::TwitchAuth(const Def &d)
: OAuthStreamKey(d)
TwitchAuth::TwitchAuth(const Def &d) : OAuthStreamKey(d)
{
if (!cef)
return;
cef->add_popup_whitelist_url(
"https://twitch.tv/popout/frankerfacez/chat?ffz-settings",
this);
"https://twitch.tv/popout/frankerfacez/chat?ffz-settings",
this);
uiLoadTimer.setSingleShot(true);
uiLoadTimer.setInterval(500);
connect(&uiLoadTimer, &QTimer::timeout,
this, &TwitchAuth::TryLoadSecondaryUIPanes);
connect(&uiLoadTimer, &QTimer::timeout, this,
&TwitchAuth::TryLoadSecondaryUIPanes);
}
bool TwitchAuth::GetChannelInfo()
@ -82,33 +75,25 @@ try {
bool success = false;
auto func = [&] () {
success = GetRemoteFile(
"https://api.twitch.tv/kraken/channel",
output,
error,
&error_code,
"application/json",
nullptr,
headers,
nullptr,
5);
auto func = [&]() {
success = GetRemoteFile("https://api.twitch.tv/kraken/channel",
output, error, &error_code,
"application/json", nullptr, headers,
nullptr, 5);
};
ExecThreadedWithoutBlocking(
func,
QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
func, QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
if (error_code == 403) {
OBSMessageBox::warning(OBSBasic::Get(),
Str("TwitchAuth.TwoFactorFail.Title"),
Str("TwitchAuth.TwoFactorFail.Text"),
true);
blog(LOG_WARNING, "%s: %s",
__FUNCTION__,
"Got 403 from Twitch, user probably does not "
"have two-factor authentication enabled on "
"their account");
Str("TwitchAuth.TwoFactorFail.Title"),
Str("TwitchAuth.TwoFactorFail.Text"),
true);
blog(LOG_WARNING, "%s: %s", __FUNCTION__,
"Got 403 from Twitch, user probably does not "
"have two-factor authentication enabled on "
"their account");
return false;
}
@ -125,10 +110,10 @@ try {
if (RetryLogin()) {
return GetChannelInfo();
}
throw ErrorInfo(error,
json["message"].string_value());
throw ErrorInfo(error, json["message"].string_value());
}
throw ErrorInfo(error, json["error_description"].string_value());
throw ErrorInfo(error,
json["error_description"].string_value());
}
name = json["name"].string_value();
@ -138,14 +123,13 @@ try {
} catch (ErrorInfo info) {
QString title = QTStr("Auth.ChannelFailure.Title");
QString text = QTStr("Auth.ChannelFailure.Text")
.arg(service(), info.message.c_str(), info.error.c_str());
.arg(service(), info.message.c_str(),
info.error.c_str());
QMessageBox::warning(OBSBasic::Get(), title, text);
blog(LOG_WARNING, "%s: %s: %s",
__FUNCTION__,
info.message.c_str(),
info.error.c_str());
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
info.error.c_str());
return false;
}
@ -155,15 +139,13 @@ void TwitchAuth::SaveInternal()
config_set_string(main->Config(), service(), "Name", name.c_str());
if (uiLoaded) {
config_set_string(main->Config(), service(), "DockState",
main->saveState().toBase64().constData());
main->saveState().toBase64().constData());
}
OAuthStreamKey::SaveInternal();
}
static inline std::string get_config_str(
OBSBasic *main,
const char *section,
const char *name)
static inline std::string get_config_str(OBSBasic *main, const char *section,
const char *name)
{
const char *val = config_get_string(main->Config(), section, name);
return val ? val : "";
@ -266,8 +248,8 @@ void TwitchAuth::LoadUI()
if (firstLoad) {
chat->setVisible(true);
} else {
const char *dockStateStr = config_get_string(main->Config(),
service(), "DockState");
const char *dockStateStr = config_get_string(
main->Config(), service(), "DockState");
QByteArray dockState =
QByteArray::fromBase64(QByteArray(dockStateStr));
main->restoreState(dockState);
@ -367,8 +349,8 @@ void TwitchAuth::LoadSecondaryUIPanes()
QSize statSize = stat->frameSize();
info->move(pos.x() + 50, pos.y() + 50);
stat->move(pos.x() + size.width() / 2 - statSize.width() / 2,
pos.y() + size.height() / 2 - statSize.height() / 2);
stat->move(pos.x() + size.width() / 2 - statSize.width() / 2,
pos.y() + size.height() / 2 - statSize.height() / 2);
feed->move(pos.x() + 100, pos.y() + 100);
if (firstLoad) {
@ -376,15 +358,15 @@ void TwitchAuth::LoadSecondaryUIPanes()
stat->setVisible(false);
feed->setVisible(false);
} else {
uint32_t lastVersion = config_get_int(App()->GlobalConfig(), "General",
"LastVersion");
uint32_t lastVersion = config_get_int(App()->GlobalConfig(),
"General", "LastVersion");
if (lastVersion <= MAKE_SEMANTIC_VERSION(23, 0, 2)) {
feed->setVisible(false);
}
const char *dockStateStr = config_get_string(main->Config(),
service(), "DockState");
const char *dockStateStr = config_get_string(
main->Config(), service(), "DockState");
QByteArray dockState =
QByteArray::fromBase64(QByteArray(dockStateStr));
main->restoreState(dockState);
@ -405,21 +387,21 @@ void TwitchAuth::TryLoadSecondaryUIPanes()
{
QPointer<TwitchAuth> this_ = this;
auto cb = [this_] (bool found)
{
auto cb = [this_](bool found) {
if (!this_) {
return;
}
if (!found) {
QMetaObject::invokeMethod(&this_->uiLoadTimer,
"start");
QMetaObject::invokeMethod(&this_->uiLoadTimer, "start");
} else {
QMetaObject::invokeMethod(this_, "LoadSecondaryUIPanes");
QMetaObject::invokeMethod(this_,
"LoadSecondaryUIPanes");
}
};
panel_cookies->CheckForCookie("https://www.twitch.tv", "auth-token", cb);
panel_cookies->CheckForCookie("https://www.twitch.tv", "auth-token",
cb);
}
bool TwitchAuth::RetryLogin()
@ -429,7 +411,8 @@ bool TwitchAuth::RetryLogin()
return false;
}
std::shared_ptr<TwitchAuth> auth = std::make_shared<TwitchAuth>(twitchDef);
std::shared_ptr<TwitchAuth> auth =
std::make_shared<TwitchAuth>(twitchDef);
std::string client_id = TWITCH_CLIENTID;
deobfuscate_str(&client_id[0], TWITCH_HASH);
@ -444,13 +427,14 @@ std::shared_ptr<Auth> TwitchAuth::Login(QWidget *parent)
return nullptr;
}
std::shared_ptr<TwitchAuth> auth = std::make_shared<TwitchAuth>(twitchDef);
std::shared_ptr<TwitchAuth> auth =
std::make_shared<TwitchAuth>(twitchDef);
std::string client_id = TWITCH_CLIENTID;
deobfuscate_str(&client_id[0], TWITCH_HASH);
if (!auth->GetToken(TWITCH_TOKEN_URL, client_id, TWITCH_SCOPE_VERSION,
QT_TO_UTF8(login.GetCode()))) {
QT_TO_UTF8(login.GetCode()))) {
return nullptr;
}
@ -475,9 +459,6 @@ static void DeleteCookies()
void RegisterTwitchAuth()
{
OAuth::RegisterOAuth(
twitchDef,
CreateTwitchAuth,
TwitchAuth::Login,
DeleteCookies);
OAuth::RegisterOAuth(twitchDef, CreateTwitchAuth, TwitchAuth::Login,
DeleteCookies);
}

View File

@ -4,7 +4,7 @@
#include <QMouseEvent>
class ClickableLabel : public QLabel {
Q_OBJECT
Q_OBJECT
public:
inline ClickableLabel(QWidget *parent = 0) : QLabel(parent) {}

View File

@ -32,10 +32,10 @@ OBSCrashReport::OBSCrashReport(QWidget *parent, const char *text)
setLayout(mainLayout);
QWidget::connect(copyButton, SIGNAL(clicked()),
this, SLOT(CopyClicked()));
QWidget::connect(exitButton, SIGNAL(clicked()),
this, SLOT(ExitClicked()));
QWidget::connect(copyButton, SIGNAL(clicked()), this,
SLOT(CopyClicked()));
QWidget::connect(exitButton, SIGNAL(clicked()), this,
SLOT(ExitClicked()));
resize(800, 600);
setWindowTitle("Oops, OBS has crashed!");

View File

@ -21,15 +21,15 @@
#define SUPPORTS_FRACTIONAL_SCALING
#endif
static inline void GetScaleAndCenterPos(
int baseCX, int baseCY, int windowCX, int windowCY,
int &x, int &y, float &scale)
static inline void GetScaleAndCenterPos(int baseCX, int baseCY, int windowCX,
int windowCY, int &x, int &y,
float &scale)
{
double windowAspect, baseAspect;
int newCX, newCY;
windowAspect = double(windowCX) / double(windowCY);
baseAspect = double(baseCX) / double(baseCY);
baseAspect = double(baseCX) / double(baseCY);
if (windowAspect > baseAspect) {
scale = float(windowCY) / float(baseCY);
@ -41,16 +41,16 @@ static inline void GetScaleAndCenterPos(
newCY = int(float(windowCX) / baseAspect);
}
x = windowCX/2 - newCX/2;
y = windowCY/2 - newCY/2;
x = windowCX / 2 - newCX / 2;
y = windowCY / 2 - newCY / 2;
}
static inline void GetCenterPosFromFixedScale(
int baseCX, int baseCY, int windowCX, int windowCY,
int &x, int &y, float scale)
static inline void GetCenterPosFromFixedScale(int baseCX, int baseCY,
int windowCX, int windowCY,
int &x, int &y, float scale)
{
x = (float(windowCX) - float(baseCX)*scale) / 2.0f;
y = (float(windowCY) - float(baseCY)*scale) / 2.0f;
x = (float(windowCX) - float(baseCX) * scale) / 2.0f;
y = (float(windowCY) - float(baseCY) * scale) / 2.0f;
}
static inline QSize GetPixelSize(QWidget *widget)

View File

@ -4,12 +4,12 @@
DoubleSlider::DoubleSlider(QWidget *parent) : SliderIgnoreScroll(parent)
{
connect(this, SIGNAL(valueChanged(int)),
this, SLOT(intValChanged(int)));
connect(this, SIGNAL(valueChanged(int)), this,
SLOT(intValChanged(int)));
}
void DoubleSlider::setDoubleConstraints(double newMin, double newMax,
double newStep, double val)
double newStep, double val)
{
minVal = newMin;
maxVal = newMax;
@ -26,7 +26,7 @@ void DoubleSlider::setDoubleConstraints(double newMin, double newMax,
void DoubleSlider::intValChanged(int val)
{
emit doubleValChanged((minVal/minStep + val) * minStep);
emit doubleValChanged((minVal / minStep + val) * minStep);
}
void DoubleSlider::setDoubleVal(double val)

View File

@ -11,8 +11,8 @@ class DoubleSlider : public SliderIgnoreScroll {
public:
DoubleSlider(QWidget *parent = nullptr);
void setDoubleConstraints(double newMin, double newMax,
double newStep, double val);
void setDoubleConstraints(double newMin, double newMax, double newStep,
double val);
signals:
void doubleValChanged(double val);

View File

@ -2,8 +2,7 @@
#include <QListWidget>
class FocusList : public QListWidget
{
class FocusList : public QListWidget {
Q_OBJECT
public:

View File

@ -5,8 +5,7 @@
#include "decklink-ui-main.h"
DecklinkOutputUI::DecklinkOutputUI(QWidget *parent)
: QDialog(parent),
ui(new Ui_Output)
: QDialog(parent), ui(new Ui_Output)
{
ui->setupUi(this);
@ -20,8 +19,10 @@ DecklinkOutputUI::DecklinkOutputUI(QWidget *parent)
connect(ui->startOutput, SIGNAL(released()), this, SLOT(StartOutput()));
connect(ui->stopOutput, SIGNAL(released()), this, SLOT(StopOutput()));
connect(ui->startPreviewOutput, SIGNAL(released()), this, SLOT(StartPreviewOutput()));
connect(ui->stopPreviewOutput, SIGNAL(released()), this, SLOT(StopPreviewOutput()));
connect(ui->startPreviewOutput, SIGNAL(released()), this,
SLOT(StartPreviewOutput()));
connect(ui->stopPreviewOutput, SIGNAL(released()), this,
SLOT(StopPreviewOutput()));
}
void DecklinkOutputUI::ShowHideDialog()
@ -43,25 +44,26 @@ void DecklinkOutputUI::SetupPropertiesView()
if (data)
obs_data_apply(settings, data);
propertiesView = new OBSPropertiesView(settings,
"decklink_output",
(PropertiesReloadCallback) obs_get_output_properties,
170);
propertiesView = new OBSPropertiesView(
settings, "decklink_output",
(PropertiesReloadCallback)obs_get_output_properties, 170);
ui->propertiesLayout->addWidget(propertiesView);
obs_data_release(settings);
connect(propertiesView, SIGNAL(Changed()), this, SLOT(PropertiesChanged()));
connect(propertiesView, SIGNAL(Changed()), this,
SLOT(PropertiesChanged()));
}
void DecklinkOutputUI::SaveSettings()
{
BPtr<char> modulePath = obs_module_get_config_path(obs_current_module(), "");
BPtr<char> modulePath =
obs_module_get_config_path(obs_current_module(), "");
os_mkdirs(modulePath);
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
"decklinkOutputProps.json");
BPtr<char> path = obs_module_get_config_path(
obs_current_module(), "decklinkOutputProps.json");
obs_data_t *settings = propertiesView->GetSettings();
if (settings)
@ -79,15 +81,15 @@ void DecklinkOutputUI::SetupPreviewPropertiesView()
if (data)
obs_data_apply(settings, data);
previewPropertiesView = new OBSPropertiesView(settings,
"decklink_output",
(PropertiesReloadCallback) obs_get_output_properties,
170);
previewPropertiesView = new OBSPropertiesView(
settings, "decklink_output",
(PropertiesReloadCallback)obs_get_output_properties, 170);
ui->previewPropertiesLayout->addWidget(previewPropertiesView);
obs_data_release(settings);
connect(previewPropertiesView, SIGNAL(Changed()), this, SLOT(PreviewPropertiesChanged()));
connect(previewPropertiesView, SIGNAL(Changed()), this,
SLOT(PreviewPropertiesChanged()));
}
void DecklinkOutputUI::SavePreviewSettings()
@ -96,15 +98,14 @@ void DecklinkOutputUI::SavePreviewSettings()
os_mkdirs(modulePath);
char *path = obs_module_get_config_path(obs_current_module(),
"decklinkPreviewOutputProps.json");
char *path = obs_module_get_config_path(
obs_current_module(), "decklinkPreviewOutputProps.json");
obs_data_t *settings = previewPropertiesView->GetSettings();
if (settings)
obs_data_save_json_safe(settings, path, "tmp", "bak");
}
void DecklinkOutputUI::StartOutput()
{
SaveSettings();
@ -121,7 +122,6 @@ void DecklinkOutputUI::PropertiesChanged()
SaveSettings();
}
void DecklinkOutputUI::StartPreviewOutput()
{
SavePreviewSettings();

View File

@ -6,7 +6,7 @@
#include "../../UI/properties-view.hpp"
class DecklinkOutputUI : public QDialog {
Q_OBJECT
Q_OBJECT
private:
OBSPropertiesView *propertiesView;
OBSPropertiesView *previewPropertiesView;

View File

@ -37,8 +37,8 @@ static struct preview_output context = {0};
OBSData load_settings()
{
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
"decklinkOutputProps.json");
BPtr<char> path = obs_module_get_config_path(
obs_current_module(), "decklinkOutputProps.json");
BPtr<char> jsonData = os_quick_read_utf8_file(path);
if (!!jsonData) {
obs_data_t *data = obs_data_create_from_json(jsonData);
@ -57,8 +57,9 @@ void output_start()
OBSData settings = load_settings();
if (settings != nullptr) {
output = obs_output_create("decklink_output",
"decklink_output", settings, NULL);
output = obs_output_create("decklink_output",
"decklink_output", settings,
NULL);
obs_output_start(output);
obs_data_release(settings);
@ -77,11 +78,10 @@ void output_stop()
}
}
OBSData load_preview_settings()
{
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
"decklinkPreviewOutputProps.json");
BPtr<char> path = obs_module_get_config_path(
obs_current_module(), "decklinkPreviewOutputProps.json");
BPtr<char> jsonData = os_quick_read_utf8_file(path);
if (!!jsonData) {
obs_data_t *data = obs_data_create_from_json(jsonData);
@ -103,8 +103,9 @@ void preview_output_start()
OBSData settings = load_preview_settings();
if (settings != nullptr) {
context.output = obs_output_create("decklink_output",
"decklink_preview_output", settings, NULL);
context.output = obs_output_create(
"decklink_output", "decklink_preview_output",
settings, NULL);
obs_get_video_info(&context.ovi);
@ -112,11 +113,14 @@ void preview_output_start()
uint32_t height = context.ovi.base_height;
obs_enter_graphics();
context.texrender = gs_texrender_create(GS_BGRA, GS_ZS_NONE);
context.stagesurface = gs_stagesurface_create(width, height, GS_BGRA);
context.texrender =
gs_texrender_create(GS_BGRA, GS_ZS_NONE);
context.stagesurface =
gs_stagesurface_create(width, height, GS_BGRA);
obs_leave_graphics();
const video_output_info *mainVOI = video_output_get_info(obs_get_video());
const video_output_info *mainVOI =
video_output_get_info(obs_get_video());
video_output_info vi = {0};
vi.format = VIDEO_FORMAT_BGRA;
@ -131,15 +135,21 @@ void preview_output_start()
video_output_open(&context.video_queue, &vi);
obs_frontend_add_event_callback(on_preview_scene_changed, &context);
obs_frontend_add_event_callback(
on_preview_scene_changed, &context);
if (obs_frontend_preview_program_mode_active()) {
context.current_source = obs_frontend_get_current_preview_scene();
context.current_source =
obs_frontend_get_current_preview_scene();
} else {
context.current_source = obs_frontend_get_current_scene();
context.current_source =
obs_frontend_get_current_scene();
}
obs_add_main_render_callback(render_preview_source, &context);
obs_add_main_render_callback(render_preview_source,
&context);
obs_output_set_media(context.output, context.video_queue, obs_get_audio());
obs_output_set_media(context.output,
context.video_queue,
obs_get_audio());
obs_output_start(context.output);
preview_output_running = true;
@ -153,8 +163,10 @@ void preview_output_stop()
obs_output_stop(context.output);
video_output_stop(context.video_queue);
obs_remove_main_render_callback(render_preview_source, &context);
obs_frontend_remove_event_callback(on_preview_scene_changed, &context);
obs_remove_main_render_callback(render_preview_source,
&context);
obs_frontend_remove_event_callback(on_preview_scene_changed,
&context);
obs_source_release(context.current_source);
@ -171,33 +183,34 @@ void preview_output_stop()
void on_preview_scene_changed(enum obs_frontend_event event, void *param)
{
auto ctx = (struct preview_output*)param;
auto ctx = (struct preview_output *)param;
switch (event) {
case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED:
case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED:
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_preview_scene();
break;
case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED:
case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED:
case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED:
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_preview_scene();
break;
case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED:
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_scene();
break;
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
if (!obs_frontend_preview_program_mode_active()) {
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_scene();
break;
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
if (!obs_frontend_preview_program_mode_active()) {
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_scene();
}
break;
default:
break;
}
break;
default:
break;
}
}
void render_preview_source(void *param, uint32_t cx, uint32_t cy)
{
auto ctx = (struct preview_output*)param;
auto ctx = (struct preview_output *)param;
if (!ctx->current_source) return;
if (!ctx->current_source)
return;
uint32_t width = obs_source_get_base_width(ctx->current_source);
uint32_t height = obs_source_get_base_height(ctx->current_source);
@ -209,7 +222,8 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy)
vec4_zero(&background);
gs_clear(GS_CLEAR_COLOR, &background, 0.0f, 0);
gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f);
gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f,
100.0f);
gs_blend_state_push();
gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO);
@ -220,18 +234,25 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy)
gs_texrender_end(ctx->texrender);
struct video_frame output_frame;
if (video_output_lock_frame(ctx->video_queue, &output_frame, 1, os_gettime_ns()))
{
gs_stage_texture(ctx->stagesurface, gs_texrender_get_texture(ctx->texrender));
if (video_output_lock_frame(ctx->video_queue, &output_frame, 1,
os_gettime_ns())) {
gs_stage_texture(
ctx->stagesurface,
gs_texrender_get_texture(ctx->texrender));
if (gs_stagesurface_map(ctx->stagesurface, &ctx->video_data, &ctx->video_linesize)) {
if (gs_stagesurface_map(ctx->stagesurface,
&ctx->video_data,
&ctx->video_linesize)) {
uint32_t linesize = output_frame.linesize[0];
for (uint32_t i = 0; i < ctx->ovi.base_height; i++) {
for (uint32_t i = 0; i < ctx->ovi.base_height;
i++) {
uint32_t dst_offset = linesize * i;
uint32_t src_offset = ctx->video_linesize * i;
memcpy(output_frame.data[0] + dst_offset,
ctx->video_data + src_offset,
linesize);
uint32_t src_offset =
ctx->video_linesize * i;
memcpy(output_frame.data[0] +
dst_offset,
ctx->video_data + src_offset,
linesize);
}
gs_stagesurface_unmap(ctx->stagesurface);
@ -245,18 +266,16 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy)
void addOutputUI(void)
{
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("Decklink Output"));
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
obs_module_text("Decklink Output"));
QMainWindow *window = (QMainWindow*)obs_frontend_get_main_window();
QMainWindow *window = (QMainWindow *)obs_frontend_get_main_window();
obs_frontend_push_ui_translation(obs_module_get_string);
doUI = new DecklinkOutputUI(window);
obs_frontend_pop_ui_translation();
auto cb = []() {
doUI->ShowHideDialog();
};
auto cb = []() { doUI->ShowHideDialog(); };
action->connect(action, &QAction::triggered, cb);
}
@ -271,7 +290,8 @@ static void OBSEvent(enum obs_frontend_event event, void *)
OBSData previewSettings = load_preview_settings();
if (previewSettings && obs_data_get_bool(previewSettings, "auto_start"))
if (previewSettings &&
obs_data_get_bool(previewSettings, "auto_start"))
preview_output_start();
}
}

View File

@ -17,7 +17,7 @@
using namespace std;
static Display* xdisplay = 0;
static Display *xdisplay = 0;
Display *disp()
{
@ -39,31 +39,22 @@ void cleanupDisplay()
static bool ewmhIsSupported()
{
Display *display = disp();
Atom netSupportingWmCheck = XInternAtom(display,
"_NET_SUPPORTING_WM_CHECK", true);
Atom netSupportingWmCheck =
XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", true);
Atom actualType;
int format = 0;
unsigned long num = 0, bytes = 0;
unsigned char *data = NULL;
Window ewmh_window = 0;
int status = XGetWindowProperty(
display,
DefaultRootWindow(display),
netSupportingWmCheck,
0L,
1L,
false,
XA_WINDOW,
&actualType,
&format,
&num,
&bytes,
&data);
int status = XGetWindowProperty(display, DefaultRootWindow(display),
netSupportingWmCheck, 0L, 1L, false,
XA_WINDOW, &actualType, &format, &num,
&bytes, &data);
if (status == Success) {
if (num > 0) {
ewmh_window = ((Window*)data)[0];
ewmh_window = ((Window *)data)[0];
}
if (data) {
XFree(data);
@ -72,21 +63,12 @@ static bool ewmhIsSupported()
}
if (ewmh_window) {
status = XGetWindowProperty(
display,
ewmh_window,
netSupportingWmCheck,
0L,
1L,
false,
XA_WINDOW,
&actualType,
&format,
&num,
&bytes,
&data);
status = XGetWindowProperty(display, ewmh_window,
netSupportingWmCheck, 0L, 1L, false,
XA_WINDOW, &actualType, &format,
&num, &bytes, &data);
if (status != Success || num == 0 ||
ewmh_window != ((Window*)data)[0]) {
ewmh_window != ((Window *)data)[0]) {
ewmh_window = 0;
}
if (status == Success && data) {
@ -111,24 +93,15 @@ static std::vector<Window> getTopLevelWindows()
Atom actualType;
int format;
unsigned long num, bytes;
Window* data = 0;
Window *data = 0;
for (int i = 0; i < ScreenCount(disp()); ++i) {
Window rootWin = RootWindow(disp(), i);
int status = XGetWindowProperty(
disp(),
rootWin,
netClList,
0L,
~0L,
false,
AnyPropertyType,
&actualType,
&format,
&num,
&bytes,
(uint8_t**)&data);
int status = XGetWindowProperty(disp(), rootWin, netClList, 0L,
~0L, false, AnyPropertyType,
&actualType, &format, &num,
&bytes, (uint8_t **)&data);
if (status != Success) {
continue;
@ -147,11 +120,10 @@ static std::string GetWindowTitle(size_t i)
{
Window w = getTopLevelWindows().at(i);
std::string windowTitle;
char* name;
char *name;
int status = XFetchName(disp(), w, &name);
if (status >= Success && name != nullptr)
{
if (status >= Success && name != nullptr) {
std::string str(name);
windowTitle = str;
}
@ -165,7 +137,7 @@ void GetWindowList(vector<string> &windows)
{
windows.resize(0);
for (size_t i = 0; i < getTopLevelWindows().size(); ++i){
for (size_t i = 0; i < getTopLevelWindows().size(); ++i) {
if (GetWindowTitle(i) != "")
windows.emplace_back(GetWindowTitle(i));
}
@ -181,24 +153,14 @@ void GetCurrentWindowTitle(string &title)
Atom actualType;
int format;
unsigned long num, bytes;
Window* data = 0;
char* name;
Window *data = 0;
char *name;
Window rootWin = RootWindow(disp(), 0);
XGetWindowProperty(
disp(),
rootWin,
active,
0L,
~0L,
false,
AnyPropertyType,
&actualType,
&format,
&num,
&bytes,
(uint8_t**)&data);
XGetWindowProperty(disp(), rootWin, active, 0L, ~0L, false,
AnyPropertyType, &actualType, &format, &num, &bytes,
(uint8_t **)&data);
int status = XFetchName(disp(), data[0], &name);

View File

@ -32,7 +32,7 @@ static bool WindowValid(HWND window)
return false;
GetClientRect(window, &rect);
styles = GetWindowLongPtr(window, GWL_STYLE);
styles = GetWindowLongPtr(window, GWL_STYLE);
ex_styles = GetWindowLongPtr(window, GWL_EXSTYLE);
if (ex_styles & WS_EX_TOOLWINDOW)

View File

@ -69,23 +69,19 @@ struct SwitcherData {
}
}
inline ~SwitcherData()
{
Stop();
}
inline ~SwitcherData() { Stop(); }
};
static SwitcherData *switcher = nullptr;
static inline QString MakeSwitchName(const QString &scene,
const QString &window)
const QString &window)
{
return QStringLiteral("[") + scene + QStringLiteral("]: ") + window;
}
SceneSwitcher::SceneSwitcher(QWidget *parent)
: QDialog(parent),
ui(new Ui_SceneSwitcher)
: QDialog(parent), ui(new Ui_SceneSwitcher)
{
ui->setupUi(this);
@ -95,7 +91,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
switcher->Prune();
BPtr<char*> scenes = obs_frontend_get_scene_names();
BPtr<char *> scenes = obs_frontend_get_scene_names();
char **temp = scenes;
while (*temp) {
const char *name = *temp;
@ -110,7 +106,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
ui->noMatchDontSwitch->setChecked(true);
ui->noMatchSwitchScene->setCurrentText(
GetWeakSourceName(switcher->nonMatchingScene).c_str());
GetWeakSourceName(switcher->nonMatchingScene).c_str());
ui->checkInterval->setValue(switcher->interval);
vector<string> windows;
@ -121,11 +117,10 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
for (auto &s : switcher->switches) {
string sceneName = GetWeakSourceName(s.scene);
QString text = MakeSwitchName(sceneName.c_str(),
s.window.c_str());
QString text =
MakeSwitchName(sceneName.c_str(), s.window.c_str());
QListWidgetItem *item = new QListWidgetItem(text,
ui->switches);
QListWidgetItem *item = new QListWidgetItem(text, ui->switches);
item->setData(Qt::UserRole, s.window.c_str());
}
@ -137,7 +132,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
loading = false;
}
void SceneSwitcher::closeEvent(QCloseEvent*)
void SceneSwitcher::closeEvent(QCloseEvent *)
{
obs_frontend_save();
}
@ -149,8 +144,7 @@ int SceneSwitcher::FindByData(const QString &window)
for (int i = 0; i < count; i++) {
QListWidgetItem *item = ui->switches->item(i);
QString itemWindow =
item->data(Qt::UserRole).toString();
QString itemWindow = item->data(Qt::UserRole).toString();
if (itemWindow == window) {
idx = i;
@ -206,16 +200,16 @@ void SceneSwitcher::on_add_clicked()
if (idx == -1) {
try {
lock_guard<mutex> lock(switcher->m);
switcher->switches.emplace_back(source,
windowName.toUtf8().constData());
QListWidgetItem *item = new QListWidgetItem(text,
ui->switches);
switcher->switches.emplace_back(
source, windowName.toUtf8().constData());
QListWidgetItem *item =
new QListWidgetItem(text, ui->switches);
item->setData(Qt::UserRole, v);
} catch (const regex_error &) {
QMessageBox::warning(this,
obs_module_text("InvalidRegex.Title"),
obs_module_text("InvalidRegex.Text"));
QMessageBox::warning(
this, obs_module_text("InvalidRegex.Title"),
obs_module_text("InvalidRegex.Text"));
}
} else {
QListWidgetItem *item = ui->switches->item(idx);
@ -274,8 +268,7 @@ void SceneSwitcher::on_startAtLaunch_toggled(bool value)
void SceneSwitcher::UpdateNonMatchingScene(const QString &name)
{
obs_source_t *scene = obs_get_source_by_name(
name.toUtf8().constData());
obs_source_t *scene = obs_get_source_by_name(name.toUtf8().constData());
obs_weak_source_t *ws = obs_source_get_weak_source(scene);
switcher->nonMatchingScene = ws;
@ -303,8 +296,7 @@ void SceneSwitcher::on_noMatchSwitch_clicked()
UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText());
}
void SceneSwitcher::on_noMatchSwitchScene_currentTextChanged(
const QString &text)
void SceneSwitcher::on_noMatchSwitchScene_currentTextChanged(const QString &text)
{
if (loading)
return;
@ -357,13 +349,13 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
for (SceneSwitch &s : switcher->switches) {
obs_data_t *array_obj = obs_data_create();
obs_source_t *source = obs_weak_source_get_source(
s.scene);
obs_source_t *source =
obs_weak_source_get_source(s.scene);
if (source) {
const char *n = obs_source_get_name(source);
obs_data_set_string(array_obj, "scene", n);
obs_data_set_string(array_obj, "window_title",
s.window.c_str());
s.window.c_str());
obs_data_array_push_back(array, array_obj);
obs_source_release(source);
}
@ -376,9 +368,9 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_set_int(obj, "interval", switcher->interval);
obs_data_set_string(obj, "non_matching_scene",
nonMatchingSceneName.c_str());
nonMatchingSceneName.c_str());
obs_data_set_bool(obj, "switch_if_not_matching",
switcher->switchIfNotMatching);
switcher->switchIfNotMatching);
obs_data_set_bool(obj, "active", switcher->th.joinable());
obs_data_set_array(obj, "switches", array);
@ -389,8 +381,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
} else {
switcher->m.lock();
obs_data_t *obj = obs_data_get_obj(save_data,
"auto-scene-switcher");
obs_data_t *obj =
obs_data_get_obj(save_data, "auto-scene-switcher");
obs_data_array_t *array = obs_data_get_array(obj, "switches");
size_t count = obs_data_array_count(array);
@ -420,8 +412,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_get_string(array_obj, "window_title");
switcher->switches.emplace_back(
GetWeakSourceByName(scene),
window);
GetWeakSourceByName(scene), window);
obs_data_release(array_obj);
}
@ -476,18 +467,18 @@ void SwitcherData::Thread()
for (SceneSwitch &s : switches) {
try {
bool matches = regex_match(
title, s.re);
title, s.re);
if (matches) {
match = true;
scene = s.scene;
break;
}
} catch (const regex_error &) {}
} catch (const regex_error &) {
}
}
}
if (!match && switchIfNotMatching &&
nonMatchingScene) {
if (!match && switchIfNotMatching && nonMatchingScene) {
match = true;
scene = nonMatchingScene;
}
@ -513,7 +504,7 @@ void SwitcherData::Thread()
void SwitcherData::Start()
{
if (!switcher->th.joinable())
switcher->th = thread([] () {switcher->Thread();});
switcher->th = thread([]() { switcher->Thread(); });
}
void SwitcherData::Stop()
@ -542,17 +533,16 @@ static void OBSEvent(enum obs_frontend_event event, void *)
extern "C" void InitSceneSwitcher()
{
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("SceneSwitcher"));
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
obs_module_text("SceneSwitcher"));
switcher = new SwitcherData;
auto cb = [] ()
{
auto cb = []() {
obs_frontend_push_ui_translation(obs_module_get_string);
QMainWindow *window =
(QMainWindow*)obs_frontend_get_main_window();
(QMainWindow *)obs_frontend_get_main_window();
SceneSwitcher ss(window);
ss.exec();

View File

@ -1,33 +1,24 @@
#include "captions-handler.hpp"
captions_handler::captions_handler(
captions_cb callback,
enum audio_format format,
uint32_t sample_rate)
captions_handler::captions_handler(captions_cb callback,
enum audio_format format,
uint32_t sample_rate)
: cb(callback)
{
if (!reset_resampler(format, sample_rate))
throw CAPTIONS_ERROR_GENERIC_FAIL;
}
bool captions_handler::reset_resampler(
enum audio_format format,
uint32_t sample_rate)
bool captions_handler::reset_resampler(enum audio_format format,
uint32_t sample_rate)
try {
obs_audio_info ai;
if (!obs_get_audio_info(&ai))
throw std::string("Failed to get OBS audio info");
resample_info src = {
ai.samples_per_sec,
AUDIO_FORMAT_FLOAT_PLANAR,
ai.speakers
};
resample_info dst = {
sample_rate,
format,
SPEAKERS_MONO
};
resample_info src = {ai.samples_per_sec, AUDIO_FORMAT_FLOAT_PLANAR,
ai.speakers};
resample_info dst = {sample_rate, format, SPEAKERS_MONO};
if (!resampler.reset(dst, src))
throw std::string("Failed to create audio resampler");
@ -46,9 +37,9 @@ void captions_handler::push_audio(const audio_data *audio)
uint64_t ts_offset;
bool success;
success = audio_resampler_resample(resampler,
out, &frames, &ts_offset,
(const uint8_t *const *)audio->data, audio->frames);
success = audio_resampler_resample(resampler, out, &frames, &ts_offset,
(const uint8_t *const *)audio->data,
audio->frames);
if (success)
pcm_data(out[0], frames);
}

View File

@ -9,10 +9,7 @@ class resampler_obj {
audio_resampler_t *resampler = nullptr;
public:
inline ~resampler_obj()
{
audio_resampler_destroy(resampler);
}
inline ~resampler_obj() { audio_resampler_destroy(resampler); }
inline bool reset(const resample_info &dst, const resample_info &src)
{
@ -21,15 +18,15 @@ public:
return !!resampler;
}
inline operator audio_resampler_t*() {return resampler;}
inline operator audio_resampler_t *() { return resampler; }
};
/* ------------------------------------------------------------------------- */
typedef std::function<void (const std::string &)> captions_cb;
typedef std::function<void(const std::string &)> captions_cb;
#define captions_error(s) std::string(obs_module_text("Captions.Error." ## s))
#define CAPTIONS_ERROR_GENERIC_FAIL captions_error("GenericFail")
#define captions_error(s) std::string(obs_module_text("Captions.Error."##s))
#define CAPTIONS_ERROR_GENERIC_FAIL captions_error("GenericFail")
/* ------------------------------------------------------------------------- */
@ -38,22 +35,17 @@ class captions_handler {
resampler_obj resampler;
protected:
inline void callback(const std::string &text)
{
cb(text);
}
inline void callback(const std::string &text) { cb(text); }
virtual void pcm_data(const void *data, size_t frames)=0;
virtual void pcm_data(const void *data, size_t frames) = 0;
/* always resamples to 1 channel */
bool reset_resampler(enum audio_format format, uint32_t sample_rate);
public:
/* throw std::string for errors shown to users */
captions_handler(
captions_cb callback,
enum audio_format format,
uint32_t sample_rate);
captions_handler(captions_cb callback, enum audio_format format,
uint32_t sample_rate);
virtual ~captions_handler() {}
void push_audio(const audio_data *audio);
@ -62,6 +54,6 @@ public:
/* ------------------------------------------------------------------------- */
struct captions_handler_info {
std::string (*name)(void);
std::string (*name)(void);
captions_handler *(*create)(captions_cb cb, const std::string &lang);
};

View File

@ -8,16 +8,17 @@
using namespace std;
#if 0
#define debugfunc(format, ...) blog(LOG_DEBUG, "[Captions] %s(" format ")", \
__FUNCTION__, ##__VA_ARGS__)
#define debugfunc(format, ...) \
blog(LOG_DEBUG, "[Captions] %s(" format ")", __FUNCTION__, \
##__VA_ARGS__)
#else
#define debugfunc(format, ...)
#endif
CaptionStream::CaptionStream(DWORD samplerate_, mssapi_captions *handler_) :
handler(handler_),
samplerate(samplerate_),
event(CreateEvent(nullptr, false, false, nullptr))
CaptionStream::CaptionStream(DWORD samplerate_, mssapi_captions *handler_)
: handler(handler_),
samplerate(samplerate_),
event(CreateEvent(nullptr, false, false, nullptr))
{
buf_info.ulMsMinNotification = 50;
buf_info.ulMsBufferSize = 500;
@ -66,15 +67,15 @@ STDMETHODIMP CaptionStream::QueryInterface(REFIID riid, void **ppv)
} else if (riid == IID_IStream) {
AddRef();
*ppv = (IStream*)this;
*ppv = (IStream *)this;
} else if (riid == IID_ISpStreamFormat) {
AddRef();
*ppv = (ISpStreamFormat*)this;
*ppv = (ISpStreamFormat *)this;
} else if (riid == IID_ISpAudio) {
AddRef();
*ppv = (ISpAudio*)this;
*ppv = (ISpAudio *)this;
} else {
*ppv = nullptr;
@ -134,8 +135,7 @@ STDMETHODIMP CaptionStream::Read(void *data, ULONG bytes, ULONG *read_bytes)
return hr;
}
STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes,
ULONG*)
STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes, ULONG *)
{
debugfunc("data, %lu, written_bytes", bytes);
UNUSED_PARAMETER(bytes);
@ -146,7 +146,7 @@ STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes,
// IStream methods
STDMETHODIMP CaptionStream::Seek(LARGE_INTEGER move, DWORD origin,
ULARGE_INTEGER *new_pos)
ULARGE_INTEGER *new_pos)
{
debugfunc("%lld, %lx, new_pos", move, origin);
UNUSED_PARAMETER(move);
@ -170,8 +170,8 @@ STDMETHODIMP CaptionStream::SetSize(ULARGE_INTEGER new_size)
}
STDMETHODIMP CaptionStream::CopyTo(IStream *stream, ULARGE_INTEGER bytes,
ULARGE_INTEGER *read_bytes,
ULARGE_INTEGER *written_bytes)
ULARGE_INTEGER *read_bytes,
ULARGE_INTEGER *written_bytes)
{
HRESULT hr;
@ -213,7 +213,7 @@ STDMETHODIMP CaptionStream::Revert(void)
}
STDMETHODIMP CaptionStream::LockRegion(ULARGE_INTEGER offset,
ULARGE_INTEGER size, DWORD type)
ULARGE_INTEGER size, DWORD type)
{
debugfunc("%llu, %llu, %ld", offset, size, type);
UNUSED_PARAMETER(offset);
@ -224,7 +224,7 @@ STDMETHODIMP CaptionStream::LockRegion(ULARGE_INTEGER offset,
}
STDMETHODIMP CaptionStream::UnlockRegion(ULARGE_INTEGER offset,
ULARGE_INTEGER size, DWORD type)
ULARGE_INTEGER size, DWORD type)
{
debugfunc("%llu, %llu, %ld", offset, size, type);
UNUSED_PARAMETER(offset);
@ -250,7 +250,7 @@ STDMETHODIMP CaptionStream::Stat(STATSTG *stg, DWORD flag)
if (flag == STATFLAG_DEFAULT) {
size_t byte_size = (wcslen(stat_name) + 1) * sizeof(wchar_t);
stg->pwcsName = (wchar_t*)CoTaskMemAlloc(byte_size);
stg->pwcsName = (wchar_t *)CoTaskMemAlloc(byte_size);
memcpy(stg->pwcsName, stat_name, byte_size);
}
@ -267,7 +267,7 @@ STDMETHODIMP CaptionStream::Clone(IStream **stream)
// ISpStreamFormat methods
STDMETHODIMP CaptionStream::GetFormat(GUID *guid,
WAVEFORMATEX **co_mem_wfex_out)
WAVEFORMATEX **co_mem_wfex_out)
{
debugfunc("guid, co_mem_wfex_out");
@ -282,7 +282,7 @@ STDMETHODIMP CaptionStream::GetFormat(GUID *guid,
void *wfex = CoTaskMemAlloc(sizeof(format));
memcpy(wfex, &format, sizeof(format));
*co_mem_wfex_out = (WAVEFORMATEX*)wfex;
*co_mem_wfex_out = (WAVEFORMATEX *)wfex;
return S_OK;
}
@ -296,7 +296,7 @@ STDMETHODIMP CaptionStream::SetState(SPAUDIOSTATE state_, ULONGLONG)
}
STDMETHODIMP CaptionStream::SetFormat(REFGUID guid_ref,
const WAVEFORMATEX *wfex)
const WAVEFORMATEX *wfex)
{
debugfunc("guid, wfex");
if (!wfex)
@ -306,7 +306,7 @@ STDMETHODIMP CaptionStream::SetFormat(REFGUID guid_ref,
lock_guard<mutex> lock(m);
memcpy(&format, wfex, sizeof(format));
if (!handler->reset_resampler(AUDIO_FORMAT_16BIT,
wfex->nSamplesPerSec))
wfex->nSamplesPerSec))
return E_FAIL;
/* 50 msec */
@ -354,7 +354,7 @@ STDMETHODIMP CaptionStream::GetBufferInfo(SPAUDIOBUFFERINFO *buf_info_)
}
STDMETHODIMP CaptionStream::GetDefaultFormat(GUID *format,
WAVEFORMATEX **co_mem_wfex_out)
WAVEFORMATEX **co_mem_wfex_out)
{
debugfunc("format, co_mem_wfex_out");
@ -365,7 +365,7 @@ STDMETHODIMP CaptionStream::GetDefaultFormat(GUID *format,
memcpy(wfex, &format, sizeof(format));
*format = SPDFID_WaveFormatEx;
*co_mem_wfex_out = (WAVEFORMATEX*)wfex;
*co_mem_wfex_out = (WAVEFORMATEX *)wfex;
return S_OK;
}

View File

@ -13,10 +13,11 @@
class CircleBuf {
circlebuf buf = {};
public:
inline ~CircleBuf() {circlebuf_free(&buf);}
inline operator circlebuf*() {return &buf;}
inline circlebuf *operator->() {return &buf;}
inline ~CircleBuf() { circlebuf_free(&buf); }
inline operator circlebuf *() { return &buf; }
inline circlebuf *operator->() { return &buf; }
};
class mssapi_captions;
@ -54,38 +55,38 @@ public:
// ISequentialStream methods
STDMETHODIMP Read(void *data, ULONG bytes, ULONG *read_bytes) override;
STDMETHODIMP Write(const void *data, ULONG bytes, ULONG *written_bytes)
override;
STDMETHODIMP Write(const void *data, ULONG bytes,
ULONG *written_bytes) override;
// IStream methods
STDMETHODIMP Seek(LARGE_INTEGER move, DWORD origin,
ULARGE_INTEGER *new_pos) override;
ULARGE_INTEGER *new_pos) override;
STDMETHODIMP SetSize(ULARGE_INTEGER new_size) override;
STDMETHODIMP CopyTo(IStream *stream, ULARGE_INTEGER bytes,
ULARGE_INTEGER *read_bytes,
ULARGE_INTEGER *written_bytes) override;
ULARGE_INTEGER *read_bytes,
ULARGE_INTEGER *written_bytes) override;
STDMETHODIMP Commit(DWORD commit_flags) override;
STDMETHODIMP Revert(void) override;
STDMETHODIMP LockRegion(ULARGE_INTEGER offset, ULARGE_INTEGER size,
DWORD type) override;
DWORD type) override;
STDMETHODIMP UnlockRegion(ULARGE_INTEGER offset, ULARGE_INTEGER size,
DWORD type) override;
DWORD type) override;
STDMETHODIMP Stat(STATSTG *stg, DWORD flags) override;
STDMETHODIMP Clone(IStream **stream) override;
// ISpStreamFormat methods
STDMETHODIMP GetFormat(GUID *guid, WAVEFORMATEX **co_mem_wfex_out)
override;
STDMETHODIMP GetFormat(GUID *guid,
WAVEFORMATEX **co_mem_wfex_out) override;
// ISpAudio methods
STDMETHODIMP SetState(SPAUDIOSTATE state, ULONGLONG reserved) override;
STDMETHODIMP SetFormat(REFGUID guid_ref, const WAVEFORMATEX *wfex)
override;
STDMETHODIMP SetFormat(REFGUID guid_ref,
const WAVEFORMATEX *wfex) override;
STDMETHODIMP GetStatus(SPAUDIOSTATUS *status) override;
STDMETHODIMP SetBufferInfo(const SPAUDIOBUFFERINFO *buf_info) override;
STDMETHODIMP GetBufferInfo(SPAUDIOBUFFERINFO *buf_info) override;
STDMETHODIMP GetDefaultFormat(GUID *format,
WAVEFORMATEX **co_mem_wfex_out) override;
WAVEFORMATEX **co_mem_wfex_out) override;
STDMETHODIMP_(HANDLE) EventHandle(void) override;
STDMETHODIMP GetVolumeLevel(ULONG *level) override;
STDMETHODIMP SetVolumeLevel(ULONG level) override;

View File

@ -1,16 +1,13 @@
#include "captions-mssapi.hpp"
#define do_log(type, format, ...) blog(type, "[Captions] " format, \
##__VA_ARGS__)
#define do_log(type, format, ...) \
blog(type, "[Captions] " format, ##__VA_ARGS__)
#define error(format, ...) do_log(LOG_ERROR, format, ##__VA_ARGS__)
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
mssapi_captions::mssapi_captions(
captions_cb callback,
const std::string &lang) try
: captions_handler(callback, AUDIO_FORMAT_16BIT, 16000)
{
mssapi_captions::mssapi_captions(captions_cb callback, const std::string &lang)
try : captions_handler(callback, AUDIO_FORMAT_16BIT, 16000) {
HRESULT hr;
std::wstring wlang;
@ -33,7 +30,7 @@ mssapi_captions::mssapi_captions(
throw HRError("SpFindBestToken failed", hr);
hr = CoCreateInstance(CLSID_SpInprocRecognizer, nullptr, CLSCTX_ALL,
__uuidof(ISpRecognizer), (void**)&recognizer);
__uuidof(ISpRecognizer), (void **)&recognizer);
if (FAILED(hr))
throw HRError("CoCreateInstance for recognizer failed", hr);
@ -50,7 +47,7 @@ mssapi_captions::mssapi_captions(
throw HRError("CreateRecoContext failed", hr);
ULONGLONG interest = SPFEI(SPEI_RECOGNITION) |
SPFEI(SPEI_END_SR_STREAM);
SPFEI(SPEI_END_SR_STREAM);
hr = context->SetInterest(interest, interest);
if (FAILED(hr))
throw HRError("SetInterest failed", hr);
@ -80,7 +77,7 @@ mssapi_captions::mssapi_captions(
throw HRError("LoadDictation failed", hr);
try {
t = std::thread([this] () {main_thread();});
t = std::thread([this]() { main_thread(); });
} catch (...) {
throw "Failed to create thread";
}
@ -133,8 +130,8 @@ try {
ISpRecoResult *result = event.RecoResult();
CoTaskMemPtr<wchar_t> text;
hr = result->GetText((ULONG)-1, (ULONG)-1,
true, &text, nullptr);
hr = result->GetText((ULONG)-1, (ULONG)-1, true,
&text, nullptr);
if (FAILED(hr))
continue;
@ -168,12 +165,7 @@ void mssapi_captions::pcm_data(const void *data, size_t frames)
}
captions_handler_info mssapi_info = {
[] () -> std::string
{
return "Microsoft Speech-to-Text";
},
[] (captions_cb cb, const std::string &lang) -> captions_handler *
{
[]() -> std::string { return "Microsoft Speech-to-Text"; },
[](captions_cb cb, const std::string &lang) -> captions_handler * {
return new mssapi_captions(cb, lang);
}
};
}};

View File

@ -27,16 +27,16 @@
class mssapi_captions : public captions_handler {
friend class CaptionStream;
ComPtr<CaptionStream> audio;
ComPtr<CaptionStream> audio;
ComPtr<ISpObjectToken> token;
ComPtr<ISpRecoGrammar> grammar;
ComPtr<ISpRecognizer> recognizer;
ComPtr<ISpRecognizer> recognizer;
ComPtr<ISpRecoContext> context;
HANDLE notify;
WinHandle stop;
std::thread t;
bool started = false;
HANDLE notify;
WinHandle stop;
std::thread t;
bool started = false;
void main_thread();

View File

@ -31,8 +31,8 @@
#include "captions-mssapi.hpp"
#define do_log(type, format, ...) blog(type, "[Captions] " format, \
##__VA_ARGS__)
#define do_log(type, format, ...) \
blog(type, "[Captions] " format, ##__VA_ARGS__)
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
@ -48,10 +48,10 @@ struct obs_captions {
unique_ptr<captions_handler> handler;
LANGID lang_id = GetUserDefaultUILanguage();
std::unordered_map<std::string, captions_handler_info&> handler_types;
std::unordered_map<std::string, captions_handler_info &> handler_types;
inline void register_handler(const char *id,
captions_handler_info &info)
captions_handler_info &info)
{
handler_types.emplace(id, info);
}
@ -60,7 +60,7 @@ struct obs_captions {
void stop();
obs_captions();
inline ~obs_captions() {stop();}
inline ~obs_captions() { stop(); }
};
static obs_captions *captions = nullptr;
@ -74,9 +74,9 @@ struct locale_info {
inline locale_info() {}
inline locale_info(const locale_info &) = delete;
inline locale_info(locale_info &&li)
: name(std::move(li.name)),
id(li.id)
{}
: name(std::move(li.name)), id(li.id)
{
}
};
static void get_valid_locale_names(vector<locale_info> &names);
@ -84,16 +84,14 @@ static bool valid_lang(LANGID id);
/* ------------------------------------------------------------------------- */
CaptionsDialog::CaptionsDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui_CaptionsDialog)
CaptionsDialog::CaptionsDialog(QWidget *parent)
: QDialog(parent), ui(new Ui_CaptionsDialog)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
auto cb = [this] (obs_source_t *source)
{
auto cb = [this](obs_source_t *source) {
uint32_t caps = obs_source_get_output_flags(source);
QString name = obs_source_get_name(source);
@ -111,8 +109,11 @@ CaptionsDialog::CaptionsDialog(QWidget *parent) :
ui->source->blockSignals(true);
ui->source->addItem(QStringLiteral(""));
ui->source->setCurrentIndex(0);
obs_enum_sources([] (void *data, obs_source_t *source) {
return (*static_cast<cb_t*>(data))(source);}, &cb);
obs_enum_sources(
[](void *data, obs_source_t *source) {
return (*static_cast<cb_t *>(data))(source);
},
&cb);
ui->source->blockSignals(false);
for (auto &ht : captions->handler_types) {
@ -232,8 +233,8 @@ static void caption_text(const std::string &text)
}
}
static void audio_capture(void*, obs_source_t*,
const struct audio_data *audio, bool)
static void audio_capture(void *, obs_source_t *,
const struct audio_data *audio, bool)
{
captions->handler->push_audio(audio);
}
@ -245,14 +246,13 @@ void obs_captions::start()
auto pair = handler_types.find(handler_id);
if (pair == handler_types.end()) {
warn("Failed to find handler '%s'",
handler_id.c_str());
warn("Failed to find handler '%s'", handler_id.c_str());
return;
}
if (!LCIDToLocaleName(lang_id, wname, 256, 0)) {
warn("Failed to get locale name: %d",
(int)GetLastError());
(int)GetLastError());
return;
}
@ -271,24 +271,24 @@ void obs_captions::start()
}
try {
captions_handler *h = pair->second.create(caption_text,
lang_name);
captions_handler *h =
pair->second.create(caption_text, lang_name);
handler.reset(h);
OBSSource s = OBSGetStrongRef(source);
obs_source_add_audio_capture_callback(s,
audio_capture, nullptr);
obs_source_add_audio_capture_callback(s, audio_capture,
nullptr);
} catch (std::string text) {
QWidget *window =
(QWidget*)obs_frontend_get_main_window();
(QWidget *)obs_frontend_get_main_window();
warn("Failed to create handler: %s", text.c_str());
QMessageBox::warning(window,
QMessageBox::warning(
window,
obs_module_text("Captions.Error.GenericFail"),
text.c_str());
}
}
}
@ -297,8 +297,8 @@ void obs_captions::stop()
{
OBSSource s = OBSGetStrongRef(source);
if (s)
obs_source_remove_audio_capture_callback(s,
audio_capture, nullptr);
obs_source_remove_audio_capture_callback(s, audio_capture,
nullptr);
handler.reset();
}
@ -332,42 +332,18 @@ static void get_valid_locale_names(vector<locale_info> &locales)
char locale_name[256];
static const LANGID default_locales[] = {
0x0409,
0x0401,
0x0402,
0x0403,
0x0404,
0x0405,
0x0406,
0x0407,
0x0408,
0x040a,
0x040b,
0x040c,
0x040d,
0x040e,
0x040f,
0x0410,
0x0411,
0x0412,
0x0413,
0x0414,
0x0415,
0x0416,
0x0417,
0x0418,
0x0419,
0x041a,
0
};
0x0409, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406,
0x0407, 0x0408, 0x040a, 0x040b, 0x040c, 0x040d, 0x040e,
0x040f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0};
/* ---------------------------------- */
LANGID def_id = GetUserDefaultUILanguage();
LANGID id = def_id;
if (valid_lang(id) && get_locale_name(id, locale_name)) {
dstr_copy(cur.name, obs_module_text(
"Captions.CurrentSystemLanguage"));
dstr_copy(cur.name,
obs_module_text("Captions.CurrentSystemLanguage"));
dstr_replace(cur.name, "%1", locale_name);
cur.id = id;
@ -381,8 +357,7 @@ static void get_valid_locale_names(vector<locale_info> &locales)
while (*locale) {
id = *locale;
if (id != def_id &&
valid_lang(id) &&
if (id != def_id && valid_lang(id) &&
get_locale_name(id, locale_name)) {
dstr_copy(cur.name, locale_name);
@ -418,17 +393,17 @@ static void obs_event(enum obs_frontend_event event, void *)
FreeCaptions();
}
static void save_caption_data(obs_data_t *save_data, bool saving, void*)
static void save_caption_data(obs_data_t *save_data, bool saving, void *)
{
if (saving) {
obs_data_t *obj = obs_data_create();
obs_data_set_string(obj, "source",
captions->source_name.c_str());
captions->source_name.c_str());
obs_data_set_bool(obj, "enabled", !!captions->handler);
obs_data_set_int(obj, "lang_id", captions->lang_id);
obs_data_set_string(obj, "provider",
captions->handler_id.c_str());
captions->handler_id.c_str());
obs_data_set_obj(save_data, "captions", obj);
obs_data_release(obj);
@ -440,15 +415,15 @@ static void save_caption_data(obs_data_t *save_data, bool saving, void*)
obj = obs_data_create();
obs_data_set_default_int(obj, "lang_id",
GetUserDefaultUILanguage());
GetUserDefaultUILanguage());
obs_data_set_default_string(obj, "provider", DEFAULT_HANDLER);
bool enabled = obs_data_get_bool(obj, "enabled");
captions->source_name = obs_data_get_string(obj, "source");
captions->lang_id = (int)obs_data_get_int(obj, "lang_id");
captions->handler_id = obs_data_get_string(obj, "provider");
captions->source = GetWeakSourceByName(
captions->source_name.c_str());
captions->source =
GetWeakSourceByName(captions->source_name.c_str());
obs_data_release(obj);
if (enabled)
@ -458,17 +433,15 @@ static void save_caption_data(obs_data_t *save_data, bool saving, void*)
extern "C" void InitCaptions()
{
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("Captions"));
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
obs_module_text("Captions"));
captions = new obs_captions;
auto cb = [] ()
{
auto cb = []() {
obs_frontend_push_ui_translation(obs_module_get_string);
QWidget *window =
(QWidget*)obs_frontend_get_main_window();
QWidget *window = (QWidget *)obs_frontend_get_main_window();
CaptionsDialog dialog(window);
dialog.exec();

View File

@ -13,19 +13,18 @@ using namespace std;
OutputTimer *ot;
OutputTimer::OutputTimer(QWidget *parent)
: QDialog(parent),
ui(new Ui_OutputTimer)
: QDialog(parent), ui(new Ui_OutputTimer)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
QObject::connect(ui->outputTimerStream, SIGNAL(clicked()), this,
SLOT(StreamingTimerButton()));
SLOT(StreamingTimerButton()));
QObject::connect(ui->outputTimerRecord, SIGNAL(clicked()), this,
SLOT(RecordingTimerButton()));
SLOT(RecordingTimerButton()));
QObject::connect(ui->buttonBox->button(QDialogButtonBox::Close),
SIGNAL(clicked()), this, SLOT(hide()));
SIGNAL(clicked()), this, SLOT(hide()));
streamingTimer = new QTimer(this);
streamingTimerDisplay = new QTimer(this);
@ -34,7 +33,7 @@ OutputTimer::OutputTimer(QWidget *parent)
recordingTimerDisplay = new QTimer(this);
}
void OutputTimer::closeEvent(QCloseEvent*)
void OutputTimer::closeEvent(QCloseEvent *)
{
obs_frontend_save();
}
@ -78,9 +77,7 @@ void OutputTimer::StreamTimerStart()
int minutes = ui->streamingTimerMinutes->value();
int seconds = ui->streamingTimerSeconds->value();
int total = (((hours * 3600) +
(minutes * 60)) +
seconds) * 1000;
int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000;
if (total == 0)
total = 1000;
@ -89,10 +86,10 @@ void OutputTimer::StreamTimerStart()
streamingTimer->setSingleShot(true);
QObject::connect(streamingTimer, SIGNAL(timeout()),
SLOT(EventStopStreaming()));
SLOT(EventStopStreaming()));
QObject::connect(streamingTimerDisplay, SIGNAL(timeout()), this,
SLOT(UpdateStreamTimerDisplay()));
SLOT(UpdateStreamTimerDisplay()));
streamingTimer->start();
streamingTimerDisplay->start(1000);
@ -112,9 +109,7 @@ void OutputTimer::RecordTimerStart()
int minutes = ui->recordingTimerMinutes->value();
int seconds = ui->recordingTimerSeconds->value();
int total = (((hours * 3600) +
(minutes * 60)) +
seconds) * 1000;
int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000;
if (total == 0)
total = 1000;
@ -123,10 +118,10 @@ void OutputTimer::RecordTimerStart()
recordingTimer->setSingleShot(true);
QObject::connect(recordingTimer, SIGNAL(timeout()),
SLOT(EventStopRecording()));
SLOT(EventStopRecording()));
QObject::connect(recordingTimerDisplay, SIGNAL(timeout()), this,
SLOT(UpdateRecordTimerDisplay()));
SLOT(UpdateRecordTimerDisplay()));
recordingTimer->start();
recordingTimerDisplay->start(1000);
@ -226,60 +221,57 @@ static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
obs_data_t *obj = obs_data_create();
obs_data_set_int(obj, "streamTimerHours",
ot->ui->streamingTimerHours->value());
ot->ui->streamingTimerHours->value());
obs_data_set_int(obj, "streamTimerMinutes",
ot->ui->streamingTimerMinutes->value());
ot->ui->streamingTimerMinutes->value());
obs_data_set_int(obj, "streamTimerSeconds",
ot->ui->streamingTimerSeconds->value());
ot->ui->streamingTimerSeconds->value());
obs_data_set_int(obj, "recordTimerHours",
ot->ui->recordingTimerHours->value());
ot->ui->recordingTimerHours->value());
obs_data_set_int(obj, "recordTimerMinutes",
ot->ui->recordingTimerMinutes->value());
ot->ui->recordingTimerMinutes->value());
obs_data_set_int(obj, "recordTimerSeconds",
ot->ui->recordingTimerSeconds->value());
ot->ui->recordingTimerSeconds->value());
obs_data_set_bool(obj, "autoStartStreamTimer",
ot->ui->autoStartStreamTimer->isChecked());
ot->ui->autoStartStreamTimer->isChecked());
obs_data_set_bool(obj, "autoStartRecordTimer",
ot->ui->autoStartRecordTimer->isChecked());
ot->ui->autoStartRecordTimer->isChecked());
obs_data_set_obj(save_data, "output-timer", obj);
obs_data_release(obj);
} else {
obs_data_t *obj = obs_data_get_obj(save_data,
"output-timer");
obs_data_t *obj = obs_data_get_obj(save_data, "output-timer");
if (!obj)
obj = obs_data_create();
ot->ui->streamingTimerHours->setValue(
obs_data_get_int(obj, "streamTimerHours"));
obs_data_get_int(obj, "streamTimerHours"));
ot->ui->streamingTimerMinutes->setValue(
obs_data_get_int(obj, "streamTimerMinutes"));
obs_data_get_int(obj, "streamTimerMinutes"));
ot->ui->streamingTimerSeconds->setValue(
obs_data_get_int(obj, "streamTimerSeconds"));
obs_data_get_int(obj, "streamTimerSeconds"));
ot->ui->recordingTimerHours->setValue(
obs_data_get_int(obj, "recordTimerHours"));
obs_data_get_int(obj, "recordTimerHours"));
ot->ui->recordingTimerMinutes->setValue(
obs_data_get_int(obj, "recordTimerMinutes"));
obs_data_get_int(obj, "recordTimerMinutes"));
ot->ui->recordingTimerSeconds->setValue(
obs_data_get_int(obj, "recordTimerSeconds"));
obs_data_get_int(obj, "recordTimerSeconds"));
ot->ui->autoStartStreamTimer->setChecked(
obs_data_get_bool(obj, "autoStartStreamTimer"));
obs_data_get_bool(obj, "autoStartStreamTimer"));
ot->ui->autoStartRecordTimer->setChecked(
obs_data_get_bool(obj, "autoStartRecordTimer"));
obs_data_get_bool(obj, "autoStartRecordTimer"));
obs_data_release(obj);
}
}
extern "C" void FreeOutputTimer()
{
}
extern "C" void FreeOutputTimer() {}
static void OBSEvent(enum obs_frontend_event event, void *)
{
@ -299,19 +291,16 @@ static void OBSEvent(enum obs_frontend_event event, void *)
extern "C" void InitOutputTimer()
{
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("OutputTimer"));
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
obs_module_text("OutputTimer"));
obs_frontend_push_ui_translation(obs_module_get_string);
QMainWindow *window = (QMainWindow*)obs_frontend_get_main_window();
QMainWindow *window = (QMainWindow *)obs_frontend_get_main_window();
ot = new OutputTimer(window);
auto cb = [] ()
{
ot->ShowHideDialog();
};
auto cb = []() { ot->ShowHideDialog(); };
obs_frontend_pop_ui_translation();

View File

@ -43,7 +43,7 @@
/* ----------------------------------------------------------------- */
using OBSScript = OBSObj<obs_script_t*, obs_script_destroy>;
using OBSScript = OBSObj<obs_script_t *, obs_script_destroy>;
struct ScriptData {
std::vector<OBSScript> scripts;
@ -92,11 +92,10 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr)
QHBoxLayout *buttonLayout = new QHBoxLayout();
QPushButton *clearButton = new QPushButton(tr("Clear"));
connect(clearButton, &QPushButton::clicked,
this, &ScriptLogWindow::ClearWindow);
connect(clearButton, &QPushButton::clicked, this,
&ScriptLogWindow::ClearWindow);
QPushButton *closeButton = new QPushButton(tr("Close"));
connect(closeButton, &QPushButton::clicked,
this, &QDialog::hide);
connect(closeButton, &QPushButton::clicked, this, &QDialog::hide);
buttonLayout->addStretch();
buttonLayout->addWidget(clearButton);
@ -112,8 +111,8 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr)
resize(600, 400);
config_t *global_config = obs_frontend_get_global_config();
const char *geom = config_get_string(global_config,
"ScriptLogWindow", "geometry");
const char *geom =
config_get_string(global_config, "ScriptLogWindow", "geometry");
if (geom != nullptr) {
QByteArray ba = QByteArray::fromBase64(QByteArray(geom));
restoreGeometry(ba);
@ -121,16 +120,15 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr)
setWindowTitle(obs_module_text("ScriptLogWindow"));
connect(edit->verticalScrollBar(), &QAbstractSlider::sliderMoved,
this, &ScriptLogWindow::ScrollChanged);
connect(edit->verticalScrollBar(), &QAbstractSlider::sliderMoved, this,
&ScriptLogWindow::ScrollChanged);
}
ScriptLogWindow::~ScriptLogWindow()
{
config_t *global_config = obs_frontend_get_global_config();
config_set_string(global_config,
"ScriptLogWindow", "geometry",
saveGeometry().toBase64().constData());
config_set_string(global_config, "ScriptLogWindow", "geometry",
saveGeometry().toBase64().constData());
}
void ScriptLogWindow::ScrollChanged(int val)
@ -180,17 +178,15 @@ void ScriptLogWindow::Clear()
/* ----------------------------------------------------------------- */
ScriptsTool::ScriptsTool()
: QWidget (nullptr),
ui (new Ui_ScriptsTool)
ScriptsTool::ScriptsTool() : QWidget(nullptr), ui(new Ui_ScriptsTool)
{
ui->setupUi(this);
RefreshLists();
#if PYTHON_UI
config_t *config = obs_frontend_get_global_config();
const char *path = config_get_string(config, "Python",
"Path" ARCH_NAME);
const char *path =
config_get_string(config, "Python", "Path" ARCH_NAME);
ui->pythonPath->setText(path);
ui->pythonPathLabel->setText(obs_module_text(PYTHONPATH_LABEL_TEXT));
#else
@ -201,7 +197,7 @@ ScriptsTool::ScriptsTool()
delete propertiesView;
propertiesView = new QWidget();
propertiesView->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding);
QSizePolicy::Expanding);
ui->propertiesLayout->addWidget(propertiesView);
}
@ -217,8 +213,8 @@ void ScriptsTool::RemoveScript(const char *path)
const char *script_path = obs_script_get_path(script);
if (strcmp(script_path, path) == 0) {
scriptData->scripts.erase(
scriptData->scripts.begin() + i);
scriptData->scripts.erase(scriptData->scripts.begin() +
i);
break;
}
}
@ -323,7 +319,8 @@ void ScriptsTool::on_addScripts_clicked()
scriptData->scripts.emplace_back(script);
QListWidgetItem *item = new QListWidgetItem(script_file);
QListWidgetItem *item =
new QListWidgetItem(script_file);
item->setData(Qt::UserRole, QString(file));
ui->scripts->addItem(item);
@ -343,8 +340,10 @@ void ScriptsTool::on_removeScripts_clicked()
QList<QListWidgetItem *> items = ui->scripts->selectedItems();
for (QListWidgetItem *item : items)
RemoveScript(item->data(Qt::UserRole).toString()
.toUtf8().constData());
RemoveScript(item->data(Qt::UserRole)
.toString()
.toUtf8()
.constData());
RefreshLists();
}
@ -352,8 +351,10 @@ void ScriptsTool::on_reloadScripts_clicked()
{
QList<QListWidgetItem *> items = ui->scripts->selectedItems();
for (QListWidgetItem *item : items)
ReloadScript(item->data(Qt::UserRole).toString()
.toUtf8().constData());
ReloadScript(item->data(Qt::UserRole)
.toString()
.toUtf8()
.constData());
on_scripts_currentRowChanged(ui->scripts->currentRow());
}
@ -368,9 +369,7 @@ void ScriptsTool::on_pythonPathBrowse_clicked()
{
QString curPath = ui->pythonPath->text();
QString newPath = QFileDialog::getExistingDirectory(
this,
ui->pythonPathLabel->text(),
curPath);
this, ui->pythonPathLabel->text(), curPath);
if (newPath.isEmpty())
return;
@ -406,14 +405,14 @@ void ScriptsTool::on_scripts_currentRowChanged(int row)
if (row == -1) {
propertiesView = new QWidget();
propertiesView->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding);
QSizePolicy::Expanding);
ui->propertiesLayout->addWidget(propertiesView);
ui->description->setText(QString());
return;
}
QByteArray array = ui->scripts->item(row)->data(Qt::UserRole)
.toString().toUtf8();
QByteArray array =
ui->scripts->item(row)->data(Qt::UserRole).toString().toUtf8();
const char *path = array.constData();
obs_script_t *script = scriptData->FindScript(path);
@ -425,9 +424,10 @@ void ScriptsTool::on_scripts_currentRowChanged(int row)
OBSData settings = obs_script_get_settings(script);
obs_data_release(settings);
propertiesView = new OBSPropertiesView(settings, script,
(PropertiesReloadCallback)obs_script_get_properties,
(PropertiesUpdateCallback)obs_script_update);
propertiesView = new OBSPropertiesView(
settings, script,
(PropertiesReloadCallback)obs_script_get_properties,
(PropertiesUpdateCallback)obs_script_update);
ui->propertiesLayout->addWidget(propertiesView);
ui->description->setText(obs_script_get_description(script));
}
@ -457,8 +457,7 @@ static void obs_event(enum obs_frontend_event event, void *)
static void load_script_data(obs_data_t *load_data, bool, void *)
{
obs_data_array_t *array = obs_data_get_array(load_data,
"scripts-tool");
obs_data_array_t *array = obs_data_get_array(load_data, "scripts-tool");
delete scriptData;
scriptData = new ScriptData;
@ -509,21 +508,19 @@ static void save_script_data(obs_data_t *save_data, bool saving, void *)
}
static void script_log(void *, obs_script_t *script, int log_level,
const char *message)
const char *message)
{
QString qmsg;
if (script) {
qmsg = QStringLiteral("[%1] %2").arg(
obs_script_get_file(script),
message);
obs_script_get_file(script), message);
} else {
qmsg = QStringLiteral("[Unknown Script] %1").arg(message);
}
QMetaObject::invokeMethod(scriptLogWindow, "AddLogMsg",
Q_ARG(int, log_level),
Q_ARG(QString, qmsg));
Q_ARG(int, log_level), Q_ARG(QString, qmsg));
}
extern "C" void InitScripts()
@ -533,13 +530,13 @@ extern "C" void InitScripts()
obs_scripting_load();
obs_scripting_set_log_callback(script_log, nullptr);
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("Scripts"));
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
obs_module_text("Scripts"));
#if PYTHON_UI
config_t *config = obs_frontend_get_global_config();
const char *python_path = config_get_string(config, "Python",
"Path" ARCH_NAME);
const char *python_path =
config_get_string(config, "Python", "Path" ARCH_NAME);
if (!obs_scripting_python_loaded() && python_path && *python_path)
obs_scripting_load_python(python_path);
@ -547,8 +544,7 @@ extern "C" void InitScripts()
scriptData = new ScriptData;
auto cb = [] ()
{
auto cb = []() {
obs_frontend_push_ui_translation(obs_module_get_string);
if (!scriptsWindow) {

View File

@ -8,8 +8,7 @@ class HScrollArea : public QScrollArea {
Q_OBJECT
public:
inline HScrollArea(QWidget *parent = nullptr)
: QScrollArea(parent)
inline HScrollArea(QWidget *parent = nullptr) : QScrollArea(parent)
{
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

View File

@ -25,13 +25,13 @@
#include "qt-wrappers.hpp"
static inline bool operator!=(const obs_key_combination_t &c1,
const obs_key_combination_t &c2)
const obs_key_combination_t &c2)
{
return c1.modifiers != c2.modifiers || c1.key != c2.key;
}
static inline bool operator==(const obs_key_combination_t &c1,
const obs_key_combination_t &c2)
const obs_key_combination_t &c2)
{
return !(c1 != c2);
}
@ -105,32 +105,34 @@ void OBSHotkeyEdit::mousePressEvent(QMouseEvent *event)
new_key.key = OBS_KEY_MOUSE3;
break;
#define MAP_BUTTON(i, j) case Qt::ExtraButton ## i: \
new_key.key = OBS_KEY_MOUSE ## j; break;
MAP_BUTTON( 1, 4);
MAP_BUTTON( 2, 5);
MAP_BUTTON( 3, 6);
MAP_BUTTON( 4, 7);
MAP_BUTTON( 5, 8);
MAP_BUTTON( 6, 9);
MAP_BUTTON( 7, 10);
MAP_BUTTON( 8, 11);
MAP_BUTTON( 9, 12);
MAP_BUTTON(10, 13);
MAP_BUTTON(11, 14);
MAP_BUTTON(12, 15);
MAP_BUTTON(13, 16);
MAP_BUTTON(14, 17);
MAP_BUTTON(15, 18);
MAP_BUTTON(16, 19);
MAP_BUTTON(17, 20);
MAP_BUTTON(18, 21);
MAP_BUTTON(19, 22);
MAP_BUTTON(20, 23);
MAP_BUTTON(21, 24);
MAP_BUTTON(22, 25);
MAP_BUTTON(23, 26);
MAP_BUTTON(24, 27);
#define MAP_BUTTON(i, j) \
case Qt::ExtraButton##i: \
new_key.key = OBS_KEY_MOUSE##j; \
break;
MAP_BUTTON(1, 4)
MAP_BUTTON(2, 5)
MAP_BUTTON(3, 6)
MAP_BUTTON(4, 7)
MAP_BUTTON(5, 8)
MAP_BUTTON(6, 9)
MAP_BUTTON(7, 10)
MAP_BUTTON(8, 11)
MAP_BUTTON(9, 12)
MAP_BUTTON(10, 13)
MAP_BUTTON(11, 14)
MAP_BUTTON(12, 15)
MAP_BUTTON(13, 16)
MAP_BUTTON(14, 17)
MAP_BUTTON(15, 18)
MAP_BUTTON(16, 19)
MAP_BUTTON(17, 20)
MAP_BUTTON(18, 21)
MAP_BUTTON(19, 22)
MAP_BUTTON(20, 23)
MAP_BUTTON(21, 24)
MAP_BUTTON(22, 25)
MAP_BUTTON(23, 26)
MAP_BUTTON(24, 27)
#undef MAP_BUTTON
}
@ -183,13 +185,13 @@ void OBSHotkeyEdit::ClearKey()
void OBSHotkeyEdit::InitSignalHandler()
{
layoutChanged = {obs_get_signal_handler(),
"hotkey_layout_change",
[](void *this_, calldata_t*)
{
auto edit = static_cast<OBSHotkeyEdit*>(this_);
QMetaObject::invokeMethod(edit, "ReloadKeyLayout");
}, this};
layoutChanged = {
obs_get_signal_handler(), "hotkey_layout_change",
[](void *this_, calldata_t *) {
auto edit = static_cast<OBSHotkeyEdit *>(this_);
QMetaObject::invokeMethod(edit, "ReloadKeyLayout");
},
this};
}
void OBSHotkeyEdit::ReloadKeyLayout()
@ -198,7 +200,7 @@ void OBSHotkeyEdit::ReloadKeyLayout()
}
void OBSHotkeyWidget::SetKeyCombinations(
const std::vector<obs_key_combination_t> &combos)
const std::vector<obs_key_combination_t> &combos)
{
if (combos.empty())
AddEdit({0, OBS_KEY_NONE});
@ -210,10 +212,8 @@ void OBSHotkeyWidget::SetKeyCombinations(
bool OBSHotkeyWidget::Changed() const
{
return changed ||
std::any_of(begin(edits), end(edits), [](OBSHotkeyEdit *edit)
{
return edit->changed;
});
std::any_of(begin(edits), end(edits),
[](OBSHotkeyEdit *edit) { return edit->changed; });
}
void OBSHotkeyWidget::Apply()
@ -230,7 +230,7 @@ void OBSHotkeyWidget::Apply()
}
void OBSHotkeyWidget::GetCombinations(
std::vector<obs_key_combination_t> &combinations) const
std::vector<obs_key_combination_t> &combinations) const
{
combinations.clear();
for (auto &edit : edits)
@ -249,21 +249,19 @@ void OBSHotkeyWidget::Save(std::vector<obs_key_combination_t> &combinations)
GetCombinations(combinations);
Apply();
auto AtomicUpdate = [&]()
{
auto AtomicUpdate = [&]() {
ignoreChangedBindings = true;
obs_hotkey_load_bindings(id,
combinations.data(), combinations.size());
obs_hotkey_load_bindings(id, combinations.data(),
combinations.size());
ignoreChangedBindings = false;
};
using AtomicUpdate_t = decltype(&AtomicUpdate);
obs_hotkey_update_atomic([](void *d)
{
(*static_cast<AtomicUpdate_t>(d))();
}, static_cast<void*>(&AtomicUpdate));
obs_hotkey_update_atomic(
[](void *d) { (*static_cast<AtomicUpdate_t>(d))(); },
static_cast<void *>(&AtomicUpdate));
}
void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
@ -285,12 +283,13 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
clear->setFlat(true);
clear->setEnabled(!obs_key_combination_is_empty(combo));
QObject::connect(edit, &OBSHotkeyEdit::KeyChanged,
[=](obs_key_combination_t new_combo)
{
clear->setEnabled(!obs_key_combination_is_empty(new_combo));
revert->setEnabled(edit->original != new_combo);
});
QObject::connect(
edit, &OBSHotkeyEdit::KeyChanged,
[=](obs_key_combination_t new_combo) {
clear->setEnabled(
!obs_key_combination_is_empty(new_combo));
revert->setEnabled(edit->original != new_combo);
});
auto add = new QPushButton;
add->setProperty("themeID", "addIconSmall");
@ -303,25 +302,18 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
remove->setFixedSize(24, 24);
remove->setFlat(true);
auto CurrentIndex = [&, remove]
{
auto res = std::find(begin(removeButtons),
end(removeButtons),
remove);
auto CurrentIndex = [&, remove] {
auto res = std::find(begin(removeButtons), end(removeButtons),
remove);
return std::distance(begin(removeButtons), res);
};
QObject::connect(add, &QPushButton::clicked,
[&, CurrentIndex]
{
QObject::connect(add, &QPushButton::clicked, [&, CurrentIndex] {
AddEdit({0, OBS_KEY_NONE}, CurrentIndex() + 1);
});
QObject::connect(remove, &QPushButton::clicked,
[&, CurrentIndex]
{
RemoveEdit(CurrentIndex());
});
[&, CurrentIndex] { RemoveEdit(CurrentIndex()); });
QHBoxLayout *subLayout = new QHBoxLayout;
subLayout->setContentsMargins(0, 4, 0, 0);
@ -346,16 +338,13 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
layout()->insertLayout(idx, subLayout);
QObject::connect(revert, &QPushButton::clicked,
edit, &OBSHotkeyEdit::ResetKey);
QObject::connect(clear, &QPushButton::clicked,
edit, &OBSHotkeyEdit::ClearKey);
QObject::connect(revert, &QPushButton::clicked, edit,
&OBSHotkeyEdit::ResetKey);
QObject::connect(clear, &QPushButton::clicked, edit,
&OBSHotkeyEdit::ClearKey);
QObject::connect(edit, &OBSHotkeyEdit::KeyChanged,
[&](obs_key_combination)
{
emit KeyChanged();
});
[&](obs_key_combination) { emit KeyChanged(); });
}
void OBSHotkeyWidget::RemoveEdit(size_t idx, bool signal)
@ -384,34 +373,35 @@ void OBSHotkeyWidget::RemoveEdit(size_t idx, bool signal)
void OBSHotkeyWidget::BindingsChanged(void *data, calldata_t *param)
{
auto widget = static_cast<OBSHotkeyWidget*>(data);
auto key = static_cast<obs_hotkey_t*>(calldata_ptr(param, "key"));
auto widget = static_cast<OBSHotkeyWidget *>(data);
auto key = static_cast<obs_hotkey_t *>(calldata_ptr(param, "key"));
QMetaObject::invokeMethod(widget, "HandleChangedBindings",
Q_ARG(obs_hotkey_id, obs_hotkey_get_id(key)));
Q_ARG(obs_hotkey_id, obs_hotkey_get_id(key)));
}
void OBSHotkeyWidget::HandleChangedBindings(obs_hotkey_id id_)
{
if (ignoreChangedBindings || id != id_) return;
if (ignoreChangedBindings || id != id_)
return;
std::vector<obs_key_combination_t> bindings;
auto LoadBindings = [&](obs_hotkey_binding_t *binding)
{
if (obs_hotkey_binding_get_hotkey_id(binding) != id) return;
auto LoadBindings = [&](obs_hotkey_binding_t *binding) {
if (obs_hotkey_binding_get_hotkey_id(binding) != id)
return;
auto get_combo = obs_hotkey_binding_get_key_combination;
bindings.push_back(get_combo(binding));
};
using LoadBindings_t = decltype(&LoadBindings);
obs_enum_hotkey_bindings([](void *data,
size_t, obs_hotkey_binding_t *binding)
{
auto LoadBindings = *static_cast<LoadBindings_t>(data);
LoadBindings(binding);
return true;
}, static_cast<void*>(&LoadBindings));
obs_enum_hotkey_bindings(
[](void *data, size_t, obs_hotkey_binding_t *binding) {
auto LoadBindings = *static_cast<LoadBindings_t>(data);
LoadBindings(binding);
return true;
},
static_cast<void *>(&LoadBindings));
while (edits.size() > 0)
RemoveEdit(edits.size() - 1, false);

View File

@ -45,10 +45,8 @@ class OBSHotkeyEdit : public QLineEdit {
Q_OBJECT;
public:
OBSHotkeyEdit(obs_key_combination_t original,
QWidget *parent=nullptr)
: QLineEdit(parent),
original(original)
OBSHotkeyEdit(obs_key_combination_t original, QWidget *parent = nullptr)
: QLineEdit(parent), original(original)
{
#ifdef __APPLE__
// disable the input cursor on OSX, focus should be clear
@ -63,9 +61,10 @@ public:
obs_key_combination_t original;
obs_key_combination_t key;
bool changed = false;
bool changed = false;
protected:
OBSSignal layoutChanged;
OBSSignal layoutChanged;
void InitSignalHandler();
@ -92,15 +91,14 @@ class OBSHotkeyWidget : public QWidget {
public:
OBSHotkeyWidget(obs_hotkey_id id, std::string name,
const std::vector<obs_key_combination_t> &combos={},
QWidget *parent=nullptr)
const std::vector<obs_key_combination_t> &combos = {},
QWidget *parent = nullptr)
: QWidget(parent),
id(id),
name(name),
bindingsChanged(obs_get_signal_handler(),
"hotkey_bindings_changed",
&OBSHotkeyWidget::BindingsChanged,
this)
&OBSHotkeyWidget::BindingsChanged, this)
{
auto layout = new QVBoxLayout;
layout->setSpacing(0);
@ -110,7 +108,7 @@ public:
SetKeyCombinations(combos);
}
void SetKeyCombinations(const std::vector<obs_key_combination_t>&);
void SetKeyCombinations(const std::vector<obs_key_combination_t> &);
obs_hotkey_id id;
std::string name;
@ -129,7 +127,7 @@ public:
}
void Apply();
void GetCombinations(std::vector<obs_key_combination_t>&) const;
void GetCombinations(std::vector<obs_key_combination_t> &) const;
void Save();
void Save(std::vector<obs_key_combination_t> &combinations);
@ -137,8 +135,8 @@ public:
void leaveEvent(QEvent *event) override;
private:
void AddEdit(obs_key_combination combo, int idx=-1);
void RemoveEdit(size_t idx, bool signal=true);
void AddEdit(obs_key_combination combo, int idx = -1);
void RemoveEdit(size_t idx, bool signal = true);
static void BindingsChanged(void *data, calldata_t *param);
@ -150,7 +148,7 @@ private:
QVBoxLayout *layout() const
{
return dynamic_cast<QVBoxLayout*>(QWidget::layout());
return dynamic_cast<QVBoxLayout *>(QWidget::layout());
}
private slots:

View File

@ -16,7 +16,7 @@ public:
}
explicit inline MenuButton(const QString &text,
QWidget *parent = nullptr)
QWidget *parent = nullptr)
: QPushButton(text, parent)
{
}

View File

@ -1,21 +1,20 @@
#include "obf.h"
#include <stdbool.h>
#define LOWER_HALFBYTE(x) ((x) & 0xF)
#define LOWER_HALFBYTE(x) ((x)&0xF)
#define UPPER_HALFBYTE(x) (((x) >> 4) & 0xF)
void deobfuscate_str(char *str, uint64_t val)
{
uint8_t *dec_val = (uint8_t*)&val;
uint8_t *dec_val = (uint8_t *)&val;
int i = 0;
while (*str != 0) {
int pos = i / 2;
bool bottom = (i % 2) == 0;
uint8_t *ch = (uint8_t*)str;
uint8_t xor = bottom ?
LOWER_HALFBYTE(dec_val[pos]) :
UPPER_HALFBYTE(dec_val[pos]);
uint8_t *ch = (uint8_t *)str;
uint8_t xor = bottom ? LOWER_HALFBYTE(dec_val[pos])
: UPPER_HALFBYTE(dec_val[pos]);
*ch ^= xor;

File diff suppressed because it is too large Load Diff

View File

@ -36,48 +36,50 @@
std::string CurrentTimeString();
std::string CurrentDateTimeString();
std::string GenerateTimeDateFilename(const char *extension, bool noSpace=false);
std::string GenerateTimeDateFilename(const char *extension,
bool noSpace = false);
std::string GenerateSpecifiedFilename(const char *extension, bool noSpace,
const char *format);
const char *format);
QObject *CreateShortcutFilter();
struct BaseLexer {
lexer lex;
public:
inline BaseLexer() {lexer_init(&lex);}
inline ~BaseLexer() {lexer_free(&lex);}
operator lexer*() {return &lex;}
inline BaseLexer() { lexer_init(&lex); }
inline ~BaseLexer() { lexer_free(&lex); }
operator lexer *() { return &lex; }
};
class OBSTranslator : public QTranslator {
Q_OBJECT
public:
virtual bool isEmpty() const override {return false;}
virtual bool isEmpty() const override { return false; }
virtual QString translate(const char *context, const char *sourceText,
const char *disambiguation, int n) const override;
const char *disambiguation,
int n) const override;
};
typedef std::function<void ()> VoidFunc;
typedef std::function<void()> VoidFunc;
class OBSApp : public QApplication {
Q_OBJECT
private:
std::string locale;
std::string theme;
ConfigFile globalConfig;
TextLookup textLookup;
OBSContext obsContext;
QPointer<OBSMainWindow> mainWindow;
profiler_name_store_t *profilerNameStore = nullptr;
std::string locale;
std::string theme;
ConfigFile globalConfig;
TextLookup textLookup;
OBSContext obsContext;
QPointer<OBSMainWindow> mainWindow;
profiler_name_store_t *profilerNameStore = nullptr;
os_inhibit_t *sleepInhibitor = nullptr;
int sleepInhibitRefs = 0;
bool enableHotkeysInFocus = true;
os_inhibit_t *sleepInhibitor = nullptr;
int sleepInhibitRefs = 0;
bool enableHotkeysInFocus = true;
std::deque<obs_frontend_translate_ui_cb> translatorHooks;
@ -93,8 +95,8 @@ private:
QPalette defaultPalette;
void ParseExtraThemeData(const char *path);
void AddExtraThemeColor(QPalette &pal, int group,
const char *name, uint32_t color);
void AddExtraThemeColor(QPalette &pal, int group, const char *name,
uint32_t color);
public:
OBSApp(int &argc, char **argv, profiler_name_store_t *store);
@ -105,19 +107,16 @@ public:
void EnableInFocusHotkeys(bool enable);
inline QMainWindow *GetMainWindow() const {return mainWindow.data();}
inline QMainWindow *GetMainWindow() const { return mainWindow.data(); }
inline config_t *GlobalConfig() const {return globalConfig;}
inline config_t *GlobalConfig() const { return globalConfig; }
inline const char *GetLocale() const
{
return locale.c_str();
}
inline const char *GetLocale() const { return locale.c_str(); }
inline const char *GetTheme() const {return theme.c_str();}
inline const char *GetTheme() const { return theme.c_str(); }
bool SetTheme(std::string name, std::string path = "");
inline lookup_t *GetTextLookup() const {return textLookup;}
inline lookup_t *GetTextLookup() const { return textLookup; }
inline const char *GetString(const char *lookupVal) const
{
@ -146,15 +145,18 @@ public:
inline void IncrementSleepInhibition()
{
if (!sleepInhibitor) return;
if (!sleepInhibitor)
return;
if (sleepInhibitRefs++ == 0)
os_inhibit_sleep_set_active(sleepInhibitor, true);
}
inline void DecrementSleepInhibition()
{
if (!sleepInhibitor) return;
if (sleepInhibitRefs == 0) return;
if (!sleepInhibitor)
return;
if (sleepInhibitRefs == 0)
return;
if (--sleepInhibitRefs == 0)
os_inhibit_sleep_set_active(sleepInhibitor, false);
}
@ -164,10 +166,7 @@ public:
translatorHooks.emplace_front(cb);
}
inline void PopUITranslation()
{
translatorHooks.pop_front();
}
inline void PopUITranslation() { translatorHooks.pop_front(); }
public slots:
void Exec(VoidFunc func);
@ -182,12 +181,21 @@ char *GetConfigPathPtr(const char *name);
int GetProgramDataPath(char *path, size_t size, const char *name);
char *GetProgramDataPathPtr(const char *name);
inline OBSApp *App() {return static_cast<OBSApp*>(qApp);}
inline OBSApp *App()
{
return static_cast<OBSApp *>(qApp);
}
inline config_t *GetGlobalConfig() {return App()->GlobalConfig();}
inline config_t *GetGlobalConfig()
{
return App()->GlobalConfig();
}
std::vector<std::pair<std::string, std::string>> GetLocaleNames();
inline const char *Str(const char *lookup) {return App()->GetString(lookup);}
inline const char *Str(const char *lookup)
{
return App()->GetString(lookup);
}
#define QTStr(lookupVal) QString::fromUtf8(Str(lookupVal))
bool GetFileSafeName(const char *name, std::string &file);
@ -197,8 +205,8 @@ bool WindowPositionValid(QRect rect);
static inline int GetProfilePath(char *path, size_t size, const char *file)
{
OBSMainWindow *window = reinterpret_cast<OBSMainWindow*>(
App()->GetMainWindow());
OBSMainWindow *window =
reinterpret_cast<OBSMainWindow *>(App()->GetMainWindow());
return window->GetProfilePath(path, size, file);
}

View File

@ -14,7 +14,7 @@ static inline bool callbacks_valid_(const char *func_name)
{
if (!c) {
blog(LOG_WARNING, "Tried to call %s with no callbacks!",
func_name);
func_name);
return false;
}
@ -26,7 +26,7 @@ static inline bool callbacks_valid_(const char *func_name)
static char **convert_string_list(vector<string> &strings)
{
size_t size = 0;
size_t string_data_offset = (strings.size() + 1) * sizeof(char*);
size_t string_data_offset = (strings.size() + 1) * sizeof(char *);
uint8_t *out;
char **ptr_list;
char *string_data;
@ -39,9 +39,9 @@ static char **convert_string_list(vector<string> &strings)
if (!size)
return 0;
out = (uint8_t*)bmalloc(size);
ptr_list = (char**)out;
string_data = (char*)(out + string_data_offset);
out = (uint8_t *)bmalloc(size);
ptr_list = (char **)out;
string_data = (char *)(out + string_data_offset);
for (auto &str : strings) {
*ptr_list = string_data;
@ -52,30 +52,27 @@ static char **convert_string_list(vector<string> &strings)
}
*ptr_list = nullptr;
return (char**)out;
return (char **)out;
}
/* ------------------------------------------------------------------------- */
void *obs_frontend_get_main_window(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_main_window()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_main_window()
: nullptr;
}
void *obs_frontend_get_main_window_handle(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_main_window_handle()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_main_window_handle()
: nullptr;
}
void *obs_frontend_get_system_tray(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_system_tray()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_system_tray()
: nullptr;
}
char **obs_frontend_get_scene_names(void)
@ -99,31 +96,32 @@ char **obs_frontend_get_scene_names(void)
void obs_frontend_get_scenes(struct obs_frontend_source_list *sources)
{
if (callbacks_valid()) c->obs_frontend_get_scenes(sources);
if (callbacks_valid())
c->obs_frontend_get_scenes(sources);
}
obs_source_t *obs_frontend_get_current_scene(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_current_scene()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_current_scene()
: nullptr;
}
void obs_frontend_set_current_scene(obs_source_t *scene)
{
if (callbacks_valid()) c->obs_frontend_set_current_scene(scene);
if (callbacks_valid())
c->obs_frontend_set_current_scene(scene);
}
void obs_frontend_get_transitions(struct obs_frontend_source_list *sources)
{
if (callbacks_valid()) c->obs_frontend_get_transitions(sources);
if (callbacks_valid())
c->obs_frontend_get_transitions(sources);
}
obs_source_t *obs_frontend_get_current_transition(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_current_transition()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_current_transition()
: nullptr;
}
void obs_frontend_set_current_transition(obs_source_t *transition)
@ -134,9 +132,8 @@ void obs_frontend_set_current_transition(obs_source_t *transition)
int obs_frontend_get_transition_duration(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_transition_duration()
: 0;
return !!callbacks_valid() ? c->obs_frontend_get_transition_duration()
: 0;
}
void obs_frontend_set_transition_duration(int duration)
@ -158,8 +155,8 @@ char **obs_frontend_get_scene_collections(void)
char *obs_frontend_get_current_scene_collection(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_current_scene_collection()
: nullptr;
? c->obs_frontend_get_current_scene_collection()
: nullptr;
}
void obs_frontend_set_current_scene_collection(const char *collection)
@ -170,9 +167,8 @@ void obs_frontend_set_current_scene_collection(const char *collection)
bool obs_frontend_add_scene_collection(const char *name)
{
return callbacks_valid()
? c->obs_frontend_add_scene_collection(name)
: false;
return callbacks_valid() ? c->obs_frontend_add_scene_collection(name)
: false;
}
char **obs_frontend_get_profiles(void)
@ -187,9 +183,8 @@ char **obs_frontend_get_profiles(void)
char *obs_frontend_get_current_profile(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_current_profile()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_current_profile()
: nullptr;
}
void obs_frontend_set_current_profile(const char *profile)
@ -200,91 +195,92 @@ void obs_frontend_set_current_profile(const char *profile)
void obs_frontend_streaming_start(void)
{
if (callbacks_valid()) c->obs_frontend_streaming_start();
if (callbacks_valid())
c->obs_frontend_streaming_start();
}
void obs_frontend_streaming_stop(void)
{
if (callbacks_valid()) c->obs_frontend_streaming_stop();
if (callbacks_valid())
c->obs_frontend_streaming_stop();
}
bool obs_frontend_streaming_active(void)
{
return !!callbacks_valid()
? c->obs_frontend_streaming_active()
: false;
return !!callbacks_valid() ? c->obs_frontend_streaming_active() : false;
}
void obs_frontend_recording_start(void)
{
if (callbacks_valid()) c->obs_frontend_recording_start();
if (callbacks_valid())
c->obs_frontend_recording_start();
}
void obs_frontend_recording_stop(void)
{
if (callbacks_valid()) c->obs_frontend_recording_stop();
if (callbacks_valid())
c->obs_frontend_recording_stop();
}
bool obs_frontend_recording_active(void)
{
return !!callbacks_valid()
? c->obs_frontend_recording_active()
: false;
return !!callbacks_valid() ? c->obs_frontend_recording_active() : false;
}
void obs_frontend_replay_buffer_start(void)
{
if (callbacks_valid()) c->obs_frontend_replay_buffer_start();
if (callbacks_valid())
c->obs_frontend_replay_buffer_start();
}
void obs_frontend_replay_buffer_save(void)
{
if (callbacks_valid()) c->obs_frontend_replay_buffer_save();
if (callbacks_valid())
c->obs_frontend_replay_buffer_save();
}
void obs_frontend_replay_buffer_stop(void)
{
if (callbacks_valid()) c->obs_frontend_replay_buffer_stop();
if (callbacks_valid())
c->obs_frontend_replay_buffer_stop();
}
bool obs_frontend_replay_buffer_active(void)
{
return !!callbacks_valid()
? c->obs_frontend_replay_buffer_active()
: false;
return !!callbacks_valid() ? c->obs_frontend_replay_buffer_active()
: false;
}
void *obs_frontend_add_tools_menu_qaction(const char *name)
{
return !!callbacks_valid()
? c->obs_frontend_add_tools_menu_qaction(name)
: nullptr;
? c->obs_frontend_add_tools_menu_qaction(name)
: nullptr;
}
void obs_frontend_add_tools_menu_item(const char *name,
obs_frontend_cb callback, void *private_data)
obs_frontend_cb callback,
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_add_tools_menu_item(name, callback,
private_data);
private_data);
}
void *obs_frontend_add_dock(void *dock)
{
return !!callbacks_valid()
? c->obs_frontend_add_dock(dock)
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_add_dock(dock) : nullptr;
}
void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_add_event_callback(callback, private_data);
}
void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_remove_event_callback(callback, private_data);
@ -292,37 +288,32 @@ void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
obs_output_t *obs_frontend_get_streaming_output(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_streaming_output()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_streaming_output()
: nullptr;
}
obs_output_t *obs_frontend_get_recording_output(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_recording_output()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_recording_output()
: nullptr;
}
obs_output_t *obs_frontend_get_replay_buffer_output(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_replay_buffer_output()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_replay_buffer_output()
: nullptr;
}
config_t *obs_frontend_get_profile_config(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_profile_config()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_profile_config()
: nullptr;
}
config_t *obs_frontend_get_global_config(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_global_config()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_global_config()
: nullptr;
}
void obs_frontend_save(void)
@ -344,28 +335,28 @@ void obs_frontend_defer_save_end(void)
}
void obs_frontend_add_save_callback(obs_frontend_save_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_add_save_callback(callback, private_data);
}
void obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_remove_save_callback(callback, private_data);
}
void obs_frontend_add_preload_callback(obs_frontend_save_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_add_preload_callback(callback, private_data);
}
void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_remove_preload_callback(callback, private_data);
@ -389,11 +380,10 @@ void obs_frontend_set_streaming_service(obs_service_t *service)
c->obs_frontend_set_streaming_service(service);
}
obs_service_t* obs_frontend_get_streaming_service(void)
obs_service_t *obs_frontend_get_streaming_service(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_streaming_service()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_streaming_service()
: nullptr;
}
void obs_frontend_save_streaming_service(void)
@ -405,8 +395,8 @@ void obs_frontend_save_streaming_service(void)
bool obs_frontend_preview_program_mode_active(void)
{
return !!callbacks_valid()
? c->obs_frontend_preview_program_mode_active()
: false;
? c->obs_frontend_preview_program_mode_active()
: false;
}
void obs_frontend_set_preview_program_mode(bool enable)
@ -429,16 +419,13 @@ void obs_frontend_set_preview_enabled(bool enable)
bool obs_frontend_preview_enabled(void)
{
return !!callbacks_valid()
? c->obs_frontend_preview_enabled()
: false;
return !!callbacks_valid() ? c->obs_frontend_preview_enabled() : false;
}
obs_source_t *obs_frontend_get_current_preview_scene(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_current_preview_scene()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_current_preview_scene()
: nullptr;
}
void obs_frontend_set_current_preview_scene(obs_source_t *scene)

View File

@ -43,7 +43,7 @@ enum obs_frontend_event {
OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED,
OBS_FRONTEND_EVENT_SCENE_COLLECTION_CLEANUP,
OBS_FRONTEND_EVENT_FINISHED_LOADING
OBS_FRONTEND_EVENT_FINISHED_LOADING,
};
/* ------------------------------------------------------------------------- */
@ -51,11 +51,11 @@ enum obs_frontend_event {
#ifndef SWIG
struct obs_frontend_source_list {
DARRAY(obs_source_t*) sources;
DARRAY(obs_source_t *) sources;
};
static inline void obs_frontend_source_list_free(
struct obs_frontend_source_list *source_list)
static inline void
obs_frontend_source_list_free(struct obs_frontend_source_list *source_list)
{
size_t num = source_list->sources.num;
for (size_t i = 0; i < num; i++)
@ -89,8 +89,8 @@ EXPORT void obs_frontend_get_scenes(struct obs_frontend_source_list *sources);
EXPORT obs_source_t *obs_frontend_get_current_scene(void);
EXPORT void obs_frontend_set_current_scene(obs_source_t *scene);
EXPORT void obs_frontend_get_transitions(
struct obs_frontend_source_list *sources);
EXPORT void
obs_frontend_get_transitions(struct obs_frontend_source_list *sources);
EXPORT obs_source_t *obs_frontend_get_current_transition(void);
EXPORT void obs_frontend_set_current_transition(obs_source_t *transition);
EXPORT int obs_frontend_get_transition_duration(void);
@ -109,37 +109,38 @@ typedef void (*obs_frontend_cb)(void *private_data);
EXPORT void *obs_frontend_add_tools_menu_qaction(const char *name);
EXPORT void obs_frontend_add_tools_menu_item(const char *name,
obs_frontend_cb callback, void *private_data);
obs_frontend_cb callback,
void *private_data);
/* takes QDockWidget and returns QAction */
EXPORT void *obs_frontend_add_dock(void *dock);
typedef void (*obs_frontend_event_cb)(enum obs_frontend_event event,
void *private_data);
void *private_data);
EXPORT void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data);
void *private_data);
EXPORT void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
void *private_data);
void *private_data);
typedef void (*obs_frontend_save_cb)(obs_data_t *save_data, bool saving,
void *private_data);
void *private_data);
EXPORT void obs_frontend_add_save_callback(obs_frontend_save_cb callback,
void *private_data);
void *private_data);
EXPORT void obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
void *private_data);
void *private_data);
EXPORT void obs_frontend_add_preload_callback(obs_frontend_save_cb callback,
void *private_data);
void *private_data);
EXPORT void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback,
void *private_data);
void *private_data);
typedef bool (*obs_frontend_translate_ui_cb)(const char *text,
const char **out);
const char **out);
EXPORT void obs_frontend_push_ui_translation(
obs_frontend_translate_ui_cb translate);
EXPORT void
obs_frontend_push_ui_translation(obs_frontend_translate_ui_cb translate);
EXPORT void obs_frontend_pop_ui_translation(void);
#endif //!SWIG
@ -169,7 +170,7 @@ EXPORT config_t *obs_frontend_get_profile_config(void);
EXPORT config_t *obs_frontend_get_global_config(void);
EXPORT void obs_frontend_set_streaming_service(obs_service_t *service);
EXPORT obs_service_t* obs_frontend_get_streaming_service(void);
EXPORT obs_service_t *obs_frontend_get_streaming_service(void);
EXPORT void obs_frontend_save_streaming_service(void);
EXPORT bool obs_frontend_preview_program_mode_active(void);

View File

@ -7,103 +7,111 @@
struct obs_frontend_callbacks {
virtual ~obs_frontend_callbacks() {}
virtual void *obs_frontend_get_main_window(void)=0;
virtual void *obs_frontend_get_main_window_handle(void)=0;
virtual void *obs_frontend_get_system_tray(void)=0;
virtual void *obs_frontend_get_main_window(void) = 0;
virtual void *obs_frontend_get_main_window_handle(void) = 0;
virtual void *obs_frontend_get_system_tray(void) = 0;
virtual void obs_frontend_get_scenes(
struct obs_frontend_source_list *sources)=0;
virtual obs_source_t *obs_frontend_get_current_scene(void)=0;
virtual void obs_frontend_set_current_scene(obs_source_t *scene)=0;
virtual void
obs_frontend_get_scenes(struct obs_frontend_source_list *sources) = 0;
virtual obs_source_t *obs_frontend_get_current_scene(void) = 0;
virtual void obs_frontend_set_current_scene(obs_source_t *scene) = 0;
virtual void obs_frontend_get_transitions(
struct obs_frontend_source_list *sources)=0;
virtual obs_source_t *obs_frontend_get_current_transition(void)=0;
virtual void obs_frontend_set_current_transition(
obs_source_t *transition)=0;
virtual int obs_frontend_get_transition_duration(void)=0;
virtual void obs_frontend_set_transition_duration(int duration)=0;
struct obs_frontend_source_list *sources) = 0;
virtual obs_source_t *obs_frontend_get_current_transition(void) = 0;
virtual void
obs_frontend_set_current_transition(obs_source_t *transition) = 0;
virtual int obs_frontend_get_transition_duration(void) = 0;
virtual void obs_frontend_set_transition_duration(int duration) = 0;
virtual void obs_frontend_get_scene_collections(
std::vector<std::string> &strings)=0;
virtual char *obs_frontend_get_current_scene_collection(void)=0;
virtual void obs_frontend_set_current_scene_collection(
const char *collection)=0;
virtual bool obs_frontend_add_scene_collection(const char *name)=0;
std::vector<std::string> &strings) = 0;
virtual char *obs_frontend_get_current_scene_collection(void) = 0;
virtual void
obs_frontend_set_current_scene_collection(const char *collection) = 0;
virtual bool obs_frontend_add_scene_collection(const char *name) = 0;
virtual void obs_frontend_get_profiles(
std::vector<std::string> &strings)=0;
virtual char *obs_frontend_get_current_profile(void)=0;
virtual void obs_frontend_set_current_profile(const char *profile)=0;
virtual void
obs_frontend_get_profiles(std::vector<std::string> &strings) = 0;
virtual char *obs_frontend_get_current_profile(void) = 0;
virtual void obs_frontend_set_current_profile(const char *profile) = 0;
virtual void obs_frontend_streaming_start(void)=0;
virtual void obs_frontend_streaming_stop(void)=0;
virtual bool obs_frontend_streaming_active(void)=0;
virtual void obs_frontend_streaming_start(void) = 0;
virtual void obs_frontend_streaming_stop(void) = 0;
virtual bool obs_frontend_streaming_active(void) = 0;
virtual void obs_frontend_recording_start(void)=0;
virtual void obs_frontend_recording_stop(void)=0;
virtual bool obs_frontend_recording_active(void)=0;
virtual void obs_frontend_recording_start(void) = 0;
virtual void obs_frontend_recording_stop(void) = 0;
virtual bool obs_frontend_recording_active(void) = 0;
virtual void obs_frontend_replay_buffer_start(void)=0;
virtual void obs_frontend_replay_buffer_start(void) = 0;
virtual void obs_frontend_replay_buffer_save(void) = 0;
virtual void obs_frontend_replay_buffer_stop(void)=0;
virtual bool obs_frontend_replay_buffer_active(void)=0;
virtual void obs_frontend_replay_buffer_stop(void) = 0;
virtual bool obs_frontend_replay_buffer_active(void) = 0;
virtual void *obs_frontend_add_tools_menu_qaction(const char *name)=0;
virtual void *obs_frontend_add_tools_menu_qaction(const char *name) = 0;
virtual void obs_frontend_add_tools_menu_item(const char *name,
obs_frontend_cb callback, void *private_data)=0;
obs_frontend_cb callback,
void *private_data) = 0;
virtual void *obs_frontend_add_dock(void *dock)=0;
virtual void *obs_frontend_add_dock(void *dock) = 0;
virtual void obs_frontend_add_event_callback(
obs_frontend_event_cb callback, void *private_data)=0;
virtual void obs_frontend_remove_event_callback(
obs_frontend_event_cb callback, void *private_data)=0;
virtual void
obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data) = 0;
virtual void
obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
void *private_data) = 0;
virtual obs_output_t *obs_frontend_get_streaming_output(void)=0;
virtual obs_output_t *obs_frontend_get_recording_output(void)=0;
virtual obs_output_t *obs_frontend_get_replay_buffer_output(void)=0;
virtual obs_output_t *obs_frontend_get_streaming_output(void) = 0;
virtual obs_output_t *obs_frontend_get_recording_output(void) = 0;
virtual obs_output_t *obs_frontend_get_replay_buffer_output(void) = 0;
virtual config_t *obs_frontend_get_profile_config(void)=0;
virtual config_t *obs_frontend_get_global_config(void)=0;
virtual config_t *obs_frontend_get_profile_config(void) = 0;
virtual config_t *obs_frontend_get_global_config(void) = 0;
virtual void obs_frontend_save(void) = 0;
virtual void obs_frontend_defer_save_begin(void) = 0;
virtual void obs_frontend_defer_save_end(void) = 0;
virtual void obs_frontend_add_save_callback(
obs_frontend_save_cb callback, void *private_data)=0;
virtual void obs_frontend_remove_save_callback(
obs_frontend_save_cb callback, void *private_data)=0;
virtual void
obs_frontend_add_save_callback(obs_frontend_save_cb callback,
void *private_data) = 0;
virtual void
obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
void *private_data) = 0;
virtual void obs_frontend_add_preload_callback(
obs_frontend_save_cb callback, void *private_data)=0;
virtual void obs_frontend_remove_preload_callback(
obs_frontend_save_cb callback, void *private_data)=0;
virtual void
obs_frontend_add_preload_callback(obs_frontend_save_cb callback,
void *private_data) = 0;
virtual void
obs_frontend_remove_preload_callback(obs_frontend_save_cb callback,
void *private_data) = 0;
virtual void obs_frontend_push_ui_translation(
obs_frontend_translate_ui_cb translate)=0;
virtual void obs_frontend_pop_ui_translation(void)=0;
obs_frontend_translate_ui_cb translate) = 0;
virtual void obs_frontend_pop_ui_translation(void) = 0;
virtual void obs_frontend_set_streaming_service(
obs_service_t *service)=0;
virtual obs_service_t *obs_frontend_get_streaming_service(void)=0;
virtual void obs_frontend_save_streaming_service()=0;
virtual void
obs_frontend_set_streaming_service(obs_service_t *service) = 0;
virtual obs_service_t *obs_frontend_get_streaming_service(void) = 0;
virtual void obs_frontend_save_streaming_service() = 0;
virtual bool obs_frontend_preview_program_mode_active(void)=0;
virtual void obs_frontend_set_preview_program_mode(bool enable)=0;
virtual void obs_frontend_preview_program_trigger_transition(void)=0;
virtual bool obs_frontend_preview_program_mode_active(void) = 0;
virtual void obs_frontend_set_preview_program_mode(bool enable) = 0;
virtual void obs_frontend_preview_program_trigger_transition(void) = 0;
virtual bool obs_frontend_preview_enabled(void)=0;
virtual void obs_frontend_set_preview_enabled(bool enable)=0;
virtual bool obs_frontend_preview_enabled(void) = 0;
virtual void obs_frontend_set_preview_enabled(bool enable) = 0;
virtual obs_source_t *obs_frontend_get_current_preview_scene(void)=0;
virtual void obs_frontend_set_current_preview_scene(obs_source_t *scene)=0;
virtual obs_source_t *obs_frontend_get_current_preview_scene(void) = 0;
virtual void
obs_frontend_set_current_preview_scene(obs_source_t *scene) = 0;
virtual void on_load(obs_data_t *settings)=0;
virtual void on_preload(obs_data_t *settings)=0;
virtual void on_save(obs_data_t *settings)=0;
virtual void on_event(enum obs_frontend_event event)=0;
virtual void on_load(obs_data_t *settings) = 0;
virtual void on_preload(obs_data_t *settings) = 0;
virtual void on_save(obs_data_t *settings) = 0;
virtual void on_event(enum obs_frontend_event event) = 0;
};
EXPORT void obs_frontend_set_callbacks_internal(
obs_frontend_callbacks *callbacks);
EXPORT void
obs_frontend_set_callbacks_internal(obs_frontend_callbacks *callbacks);

View File

@ -37,8 +37,8 @@ using namespace std;
#include <util/windows/HRError.hpp>
#include <util/windows/ComPtr.hpp>
static inline bool check_path(const char* data, const char *path,
string &output)
static inline bool check_path(const char *data, const char *path,
string &output)
{
ostringstream str;
str << path << data;
@ -65,10 +65,10 @@ bool InitApplicationBundle()
string GetDefaultVideoSavePath()
{
wchar_t path_utf16[MAX_PATH];
char path_utf8[MAX_PATH] = {};
char path_utf8[MAX_PATH] = {};
SHGetFolderPathW(NULL, CSIDL_MYVIDEO, NULL, SHGFP_TYPE_CURRENT,
path_utf16);
path_utf16);
os_wcs_to_utf8(path_utf16, wcslen(path_utf16), path_utf8, MAX_PATH);
return string(path_utf8);
@ -79,18 +79,18 @@ static vector<string> GetUserPreferredLocales()
vector<string> result;
ULONG num, length = 0;
if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num,
nullptr, &length))
if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num, nullptr,
&length))
return result;
vector<wchar_t> buffer(length);
if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num,
&buffer.front(), &length))
&buffer.front(), &length))
return result;
result.reserve(num);
auto start = begin(buffer);
auto end_ = end(buffer);
auto end_ = end(buffer);
decltype(start) separator;
while ((separator = find(start, end_, 0)) != end_) {
if (result.size() == num)
@ -162,7 +162,7 @@ uint32_t GetWindowsVersion()
void SetAeroEnabled(bool enable)
{
static HRESULT (WINAPI *func)(UINT) = nullptr;
static HRESULT(WINAPI * func)(UINT) = nullptr;
static bool failed = false;
if (!func) {
@ -176,8 +176,8 @@ void SetAeroEnabled(bool enable)
return;
}
func = reinterpret_cast<decltype(func)>(GetProcAddress(dwm,
"DwmEnableComposition"));
func = reinterpret_cast<decltype(func)>(
GetProcAddress(dwm, "DwmEnableComposition"));
if (!func) {
failed = true;
return;
@ -197,7 +197,7 @@ void SetAlwaysOnTop(QWidget *window, bool enable)
{
HWND hwnd = (HWND)window->winId();
SetWindowPos(hwnd, enable ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
void SetProcessPriority(const char *priority)
@ -208,11 +208,13 @@ void SetProcessPriority(const char *priority)
if (strcmp(priority, "High") == 0)
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
else if (strcmp(priority, "AboveNormal") == 0)
SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
SetPriorityClass(GetCurrentProcess(),
ABOVE_NORMAL_PRIORITY_CLASS);
else if (strcmp(priority, "Normal") == 0)
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
else if (strcmp(priority, "BelowNormal") == 0)
SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
SetPriorityClass(GetCurrentProcess(),
BELOW_NORMAL_PRIORITY_CLASS);
else if (strcmp(priority, "Idle") == 0)
SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
}
@ -227,16 +229,16 @@ void SetWin32DropStyle(QWidget *window)
bool DisableAudioDucking(bool disable)
{
ComPtr<IMMDeviceEnumerator> devEmum;
ComPtr<IMMDevice> device;
ComPtr<IMMDeviceEnumerator> devEmum;
ComPtr<IMMDevice> device;
ComPtr<IAudioSessionManager2> sessionManager2;
ComPtr<IAudioSessionControl> sessionControl;
ComPtr<IAudioSessionControl> sessionControl;
ComPtr<IAudioSessionControl2> sessionControl2;
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator),
nullptr, CLSCTX_INPROC_SERVER,
__uuidof(IMMDeviceEnumerator),
(void **)&devEmum);
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IMMDeviceEnumerator),
(void **)&devEmum);
if (FAILED(result))
return false;
@ -245,13 +247,13 @@ bool DisableAudioDucking(bool disable)
return false;
result = device->Activate(__uuidof(IAudioSessionManager2),
CLSCTX_INPROC_SERVER, nullptr,
(void **)&sessionManager2);
CLSCTX_INPROC_SERVER, nullptr,
(void **)&sessionManager2);
if (FAILED(result))
return false;
result = sessionManager2->GetAudioSessionControl(nullptr, 0,
&sessionControl);
&sessionControl);
if (FAILED(result))
return false;

View File

@ -29,8 +29,8 @@
#include "platform.hpp"
using namespace std;
static inline bool check_path(const char* data, const char *path,
string &output)
static inline bool check_path(const char *data, const char *path,
string &output)
{
ostringstream str;
str << path << data;

View File

@ -48,6 +48,7 @@ struct RunOnceMutexData;
class RunOnceMutex {
RunOnceMutexData *data = nullptr;
public:
RunOnceMutex(RunOnceMutexData *data_) : data(data_) {}
RunOnceMutex(const RunOnceMutex &rom) = delete;

File diff suppressed because it is too large Load Diff

View File

@ -10,8 +10,7 @@ class OBSPropertiesView;
class QLabel;
typedef obs_properties_t *(*PropertiesReloadCallback)(void *obj);
typedef void (*PropertiesUpdateCallback)(void *obj,
obs_data_t *settings);
typedef void (*PropertiesUpdateCallback)(void *obj, obs_data_t *settings);
/* ------------------------------------------------------------------------- */
@ -22,8 +21,8 @@ class WidgetInfo : public QObject {
private:
OBSPropertiesView *view;
obs_property_t *property;
QWidget *widget;
obs_property_t *property;
QWidget *widget;
void BoolChanged(const char *setting);
void IntChanged(const char *setting);
@ -41,9 +40,10 @@ private:
public:
inline WidgetInfo(OBSPropertiesView *view_, obs_property_t *prop,
QWidget *widget_)
QWidget *widget_)
: view(view_), property(prop), widget(widget_)
{}
{
}
public slots:
@ -72,37 +72,38 @@ class OBSPropertiesView : public VScrollArea {
std::unique_ptr<obs_properties_t, properties_delete_t>;
private:
QWidget *widget = nullptr;
properties_t properties;
OBSData settings;
void *obj = nullptr;
std::string type;
PropertiesReloadCallback reloadCallback;
PropertiesUpdateCallback callback = nullptr;
int minSize;
QWidget *widget = nullptr;
properties_t properties;
OBSData settings;
void *obj = nullptr;
std::string type;
PropertiesReloadCallback reloadCallback;
PropertiesUpdateCallback callback = nullptr;
int minSize;
std::vector<std::unique_ptr<WidgetInfo>> children;
std::string lastFocused;
QWidget *lastWidget = nullptr;
bool deferUpdate;
std::string lastFocused;
QWidget *lastWidget = nullptr;
bool deferUpdate;
QWidget *NewWidget(obs_property_t *prop, QWidget *widget,
const char *signal);
const char *signal);
QWidget *AddCheckbox(obs_property_t *prop);
QWidget *AddText(obs_property_t *prop, QFormLayout *layout,
QLabel *&label);
QLabel *&label);
void AddPath(obs_property_t *prop, QFormLayout *layout, QLabel **label);
void AddInt(obs_property_t *prop, QFormLayout *layout, QLabel **label);
void AddFloat(obs_property_t *prop, QFormLayout *layout,
QLabel**label);
QLabel **label);
QWidget *AddList(obs_property_t *prop, bool &warning);
void AddEditableList(obs_property_t *prop, QFormLayout *layout,
QLabel *&label);
QLabel *&label);
QWidget *AddButton(obs_property_t *prop);
void AddColor(obs_property_t *prop, QFormLayout *layout, QLabel *&label);
void AddColor(obs_property_t *prop, QFormLayout *layout,
QLabel *&label);
void AddFont(obs_property_t *prop, QFormLayout *layout, QLabel *&label);
void AddFrameRate(obs_property_t *prop, bool &warning,
QFormLayout *layout, QLabel *&label);
QFormLayout *layout, QLabel *&label);
void AddGroup(obs_property_t *prop, QFormLayout *layout);
@ -125,15 +126,14 @@ signals:
public:
OBSPropertiesView(OBSData settings, void *obj,
PropertiesReloadCallback reloadCallback,
PropertiesUpdateCallback callback,
int minSize = 0);
PropertiesReloadCallback reloadCallback,
PropertiesUpdateCallback callback, int minSize = 0);
OBSPropertiesView(OBSData settings, const char *type,
PropertiesReloadCallback reloadCallback,
int minSize = 0);
PropertiesReloadCallback reloadCallback,
int minSize = 0);
inline obs_data_t *GetSettings() const {return settings;}
inline obs_data_t *GetSettings() const { return settings; }
inline void UpdateSettings() {callback(obj, settings);}
inline bool DeferUpdate() const {return deferUpdate;}
inline void UpdateSettings() { callback(obj, settings); }
inline bool DeferUpdate() const { return deferUpdate; }
};

View File

@ -15,13 +15,13 @@
#endif
static bool operator!=(const media_frames_per_second &a,
const media_frames_per_second &b)
const media_frames_per_second &b)
{
return a.numerator != b.numerator || a.denominator != b.denominator;
}
static bool operator==(const media_frames_per_second &a,
const media_frames_per_second &b)
const media_frames_per_second &b)
{
return !(a != b);
}
@ -36,27 +36,27 @@ class OBSFrameRatePropertyWidget : public QWidget {
public:
frame_rate_ranges_t fps_ranges;
QComboBox *modeSelect = nullptr;
QStackedWidget *modeDisplay = nullptr;
QComboBox *modeSelect = nullptr;
QStackedWidget *modeDisplay = nullptr;
QWidget *labels = nullptr;
QLabel *currentFPS = nullptr;
QLabel *timePerFrame = nullptr;
QLabel *minLabel = nullptr;
QLabel *maxLabel = nullptr;
QWidget *labels = nullptr;
QLabel *currentFPS = nullptr;
QLabel *timePerFrame = nullptr;
QLabel *minLabel = nullptr;
QLabel *maxLabel = nullptr;
QComboBox *simpleFPS = nullptr;
QComboBox *simpleFPS = nullptr;
QComboBox *fpsRange = nullptr;
QSpinBox *numEdit = nullptr;
QSpinBox *denEdit = nullptr;
QComboBox *fpsRange = nullptr;
QSpinBox *numEdit = nullptr;
QSpinBox *denEdit = nullptr;
bool updating = false;
bool updating = false;
const char *name = nullptr;
obs_data_t *settings = nullptr;
const char *name = nullptr;
obs_data_t *settings = nullptr;
QLabel *warningLabel = nullptr;
QLabel *warningLabel = nullptr;
OBSFrameRatePropertyWidget() = default;
};

View File

@ -8,23 +8,18 @@
static inline long long color_to_int(QColor color)
{
auto shift = [&](unsigned val, int shift)
{
auto shift = [&](unsigned val, int shift) {
return ((val & 0xff) << shift);
};
return shift(color.red(), 0) |
shift(color.green(), 8) |
shift(color.blue(), 16) |
shift(color.alpha(), 24);
return shift(color.red(), 0) | shift(color.green(), 8) |
shift(color.blue(), 16) | shift(color.alpha(), 24);
}
static inline QColor rgba_to_color(uint32_t rgba)
{
return QColor::fromRgb(rgba & 0xFF,
(rgba >> 8) & 0xFF,
(rgba >> 16) & 0xFF,
(rgba >> 24) & 0xFF);
return QColor::fromRgb(rgba & 0xFF, (rgba >> 8) & 0xFF,
(rgba >> 16) & 0xFF, (rgba >> 24) & 0xFF);
}
OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
@ -37,8 +32,7 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
setAttribute(Qt::WA_DontCreateNativeAncestors);
setAttribute(Qt::WA_NativeWindow);
auto windowVisible = [this] (bool visible)
{
auto windowVisible = [this](bool visible) {
if (!visible)
return;
@ -46,12 +40,12 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
CreateDisplay();
} else {
QSize size = GetPixelSize(this);
obs_display_resize(display, size.width(), size.height());
obs_display_resize(display, size.width(),
size.height());
}
};
auto sizeChanged = [this] (QScreen*)
{
auto sizeChanged = [this](QScreen *) {
CreateDisplay();
QSize size = GetPixelSize(this);
@ -89,11 +83,11 @@ void OBSQTDisplay::CreateDisplay()
QSize size = GetPixelSize(this);
gs_init_data info = {};
info.cx = size.width();
info.cy = size.height();
info.format = GS_RGBA;
info.zsformat = GS_ZS_NONE;
gs_init_data info = {};
info.cx = size.width();
info.cy = size.height();
info.format = GS_RGBA;
info.zsformat = GS_ZS_NONE;
QTToGSWindow(winId(), info.window);

View File

@ -7,9 +7,9 @@
class OBSQTDisplay : public QWidget {
Q_OBJECT
Q_PROPERTY(QColor displayBackgroundColor MEMBER backgroundColor
READ GetDisplayBackgroundColor
WRITE SetDisplayBackgroundColor)
Q_PROPERTY(QColor displayBackgroundColor MEMBER backgroundColor READ
GetDisplayBackgroundColor WRITE
SetDisplayBackgroundColor)
OBSDisplay display;
@ -24,11 +24,11 @@ signals:
public:
OBSQTDisplay(QWidget *parent = nullptr,
Qt::WindowFlags flags = nullptr);
Qt::WindowFlags flags = nullptr);
virtual QPaintEngine *paintEngine() const override;
inline obs_display_t *GetDisplay() const {return display;}
inline obs_display_t *GetDisplay() const { return display; }
uint32_t backgroundColor = GREY_COLOR_BACKGROUND;

View File

@ -45,20 +45,17 @@ void OBSErrorBox(QWidget *parent, const char *msg, ...)
va_end(args);
}
QMessageBox::StandardButton OBSMessageBox::question(
QWidget *parent,
const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
QMessageBox::StandardButton
OBSMessageBox::question(QWidget *parent, const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
{
QMessageBox mb(QMessageBox::Question,
title, text, buttons,
parent);
QMessageBox mb(QMessageBox::Question, title, text, buttons, parent);
mb.setDefaultButton(defaultButton);
if (buttons & QMessageBox::Ok) \
if (buttons & QMessageBox::Ok)
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
#define translate_button(x) \
#define translate_button(x) \
if (buttons & QMessageBox::x) \
mb.setButtonText(QMessageBox::x, QTStr(#x));
translate_button(Open);
@ -78,41 +75,31 @@ QMessageBox::StandardButton OBSMessageBox::question(
return (QMessageBox::StandardButton)mb.exec();
}
void OBSMessageBox::information(
QWidget *parent,
const QString &title,
const QString &text)
void OBSMessageBox::information(QWidget *parent, const QString &title,
const QString &text)
{
QMessageBox mb(QMessageBox::Information,
title, text, QMessageBox::Ok,
parent);
QMessageBox mb(QMessageBox::Information, title, text, QMessageBox::Ok,
parent);
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
mb.exec();
}
void OBSMessageBox::warning(
QWidget *parent,
const QString &title,
const QString &text,
bool enableRichText)
void OBSMessageBox::warning(QWidget *parent, const QString &title,
const QString &text, bool enableRichText)
{
QMessageBox mb(QMessageBox::Warning,
title, text, QMessageBox::Ok,
parent);
QMessageBox mb(QMessageBox::Warning, title, text, QMessageBox::Ok,
parent);
if (enableRichText)
mb.setTextFormat(Qt::RichText);
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
mb.exec();
}
void OBSMessageBox::critical(
QWidget *parent,
const QString &title,
const QString &text)
void OBSMessageBox::critical(QWidget *parent, const QString &title,
const QString &text)
{
QMessageBox mb(QMessageBox::Critical,
title, text, QMessageBox::Ok,
parent);
QMessageBox mb(QMessageBox::Critical, title, text, QMessageBox::Ok,
parent);
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
mb.exec();
}
@ -156,13 +143,13 @@ uint32_t TranslateQtKeyboardEventModifiers(Qt::KeyboardModifiers mods)
}
QDataStream &operator<<(QDataStream &out,
const std::vector<std::shared_ptr<OBSSignal>> &)
const std::vector<std::shared_ptr<OBSSignal>> &)
{
return out;
}
QDataStream &operator>>(QDataStream &in,
std::vector<std::shared_ptr<OBSSignal>> &)
std::vector<std::shared_ptr<OBSSignal>> &)
{
return in;
}
@ -186,7 +173,7 @@ QDataStream &operator>>(QDataStream &in, OBSScene &scene)
QDataStream &operator<<(QDataStream &out, const OBSSceneItem &si)
{
obs_scene_t *scene = obs_sceneitem_get_scene(si);
obs_scene_t *scene = obs_sceneitem_get_scene(si);
obs_source_t *source = obs_sceneitem_get_source(si);
return out << QString(obs_source_get_name(obs_scene_get_source(scene)))
<< QString(obs_source_get_name(source));
@ -234,15 +221,12 @@ void DeleteLayout(QLayout *layout)
class QuickThread : public QThread {
public:
explicit inline QuickThread(std::function<void()> func_)
: func(func_)
{}
explicit inline QuickThread(std::function<void()> func_) : func(func_)
{
}
private:
virtual void run() override
{
func();
}
virtual void run() override { func(); }
std::function<void()> func;
};
@ -258,11 +242,10 @@ void ExecuteFuncSafeBlock(std::function<void()> func)
{
QEventLoop eventLoop;
auto wait = [&] ()
{
auto wait = [&]() {
func();
QMetaObject::invokeMethod(&eventLoop, "quit",
Qt::QueuedConnection);
Qt::QueuedConnection);
};
os_atomic_inc_long(&insideEventLoop);
@ -273,10 +256,8 @@ void ExecuteFuncSafeBlock(std::function<void()> func)
os_atomic_dec_long(&insideEventLoop);
}
void ExecuteFuncSafeBlockMsgBox(
std::function<void()> func,
const QString &title,
const QString &text)
void ExecuteFuncSafeBlockMsgBox(std::function<void()> func,
const QString &title, const QString &text)
{
QMessageBox dlg;
dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowCloseButtonHint);
@ -284,8 +265,7 @@ void ExecuteFuncSafeBlockMsgBox(
dlg.setText(text);
dlg.setStandardButtons(0);
auto wait = [&] ()
{
auto wait = [&]() {
func();
QMetaObject::invokeMethod(&dlg, "accept", Qt::QueuedConnection);
};
@ -305,10 +285,8 @@ void EnableThreadedMessageBoxes(bool enable)
enable_message_boxes = enable;
}
void ExecThreadedWithoutBlocking(
std::function<void()> func,
const QString &title,
const QString &text)
void ExecThreadedWithoutBlocking(std::function<void()> func,
const QString &title, const QString &text)
{
if (!enable_message_boxes)
ExecuteFuncSafeBlock(func);

View File

@ -38,25 +38,19 @@ struct gs_window;
class OBSMessageBox {
public:
static QMessageBox::StandardButton question(
QWidget *parent,
const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons = QMessageBox::StandardButtons( QMessageBox::Yes | QMessageBox::No ),
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
static void information(
QWidget *parent,
const QString &title,
const QString &text);
static void warning(
QWidget *parent,
const QString &title,
const QString &text,
bool enableRichText = false);
static void critical(
QWidget *parent,
const QString &title,
const QString &text);
static QMessageBox::StandardButton
question(QWidget *parent, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons =
QMessageBox::StandardButtons(QMessageBox::Yes |
QMessageBox::No),
QMessageBox::StandardButton defaultButton =
QMessageBox::NoButton);
static void information(QWidget *parent, const QString &title,
const QString &text);
static void warning(QWidget *parent, const QString &title,
const QString &text, bool enableRichText = false);
static void critical(QWidget *parent, const QString &title,
const QString &text);
};
void OBSErrorBox(QWidget *parent, const char *msg, ...);
@ -65,10 +59,11 @@ void QTToGSWindow(WId windowId, gs_window &gswindow);
uint32_t TranslateQtKeyboardEventModifiers(Qt::KeyboardModifiers mods);
QDataStream &operator<<(QDataStream &out,
const std::vector<std::shared_ptr<OBSSignal>> &signal_vec);
QDataStream &
operator<<(QDataStream &out,
const std::vector<std::shared_ptr<OBSSignal>> &signal_vec);
QDataStream &operator>>(QDataStream &in,
std::vector<std::shared_ptr<OBSSignal>> &signal_vec);
std::vector<std::shared_ptr<OBSSignal>> &signal_vec);
QDataStream &operator<<(QDataStream &out, const OBSScene &scene);
QDataStream &operator>>(QDataStream &in, OBSScene &scene);
QDataStream &operator<<(QDataStream &out, const OBSSceneItem &si);
@ -77,18 +72,14 @@ QDataStream &operator>>(QDataStream &in, OBSSceneItem &si);
QThread *CreateQThread(std::function<void()> func);
void ExecuteFuncSafeBlock(std::function<void()> func);
void ExecuteFuncSafeBlockMsgBox(
std::function<void()> func,
const QString &title,
const QString &text);
void ExecuteFuncSafeBlockMsgBox(std::function<void()> func,
const QString &title, const QString &text);
/* allows executing without message boxes if starting up, otherwise with a
* message box */
void EnableThreadedMessageBoxes(bool enable);
void ExecThreadedWithoutBlocking(
std::function<void()> func,
const QString &title,
const QString &text);
void ExecThreadedWithoutBlocking(std::function<void()> func,
const QString &title, const QString &text);
class SignalBlocker {
QWidget *widget;
@ -100,10 +91,7 @@ public:
blocked = widget->blockSignals(true);
}
inline ~SignalBlocker()
{
widget->blockSignals(blocked);
}
inline ~SignalBlocker() { widget->blockSignals(blocked); }
};
void DeleteLayout(QLayout *layout);
@ -111,6 +99,6 @@ void DeleteLayout(QLayout *layout);
static inline Qt::ConnectionType WaitConnection()
{
return QThread::currentThread() == qApp->thread()
? Qt::DirectConnection
: Qt::BlockingQueuedConnection;
? Qt::DirectConnection
: Qt::BlockingQueuedConnection;
}

View File

@ -22,7 +22,7 @@
using namespace std;
static auto curl_deleter = [] (CURL *curl) {curl_easy_cleanup(curl);};
static auto curl_deleter = [](CURL *curl) { curl_easy_cleanup(curl); };
using Curl = unique_ptr<CURL, decltype(curl_deleter)>;
static size_t string_write(char *ptr, size_t size, size_t nmemb, string &str)
@ -53,12 +53,11 @@ void RemoteTextThread::run()
struct curl_slist *header = nullptr;
string str;
header = curl_slist_append(header,
versionString.c_str());
header = curl_slist_append(header, versionString.c_str());
if (!contentTypeString.empty()) {
header = curl_slist_append(header,
contentTypeString.c_str());
contentTypeString.c_str());
}
for (std::string &h : extraHeaders)
@ -66,18 +65,15 @@ void RemoteTextThread::run()
curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str());
curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, "");
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER,
header);
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER,
error);
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header);
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error);
curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION,
string_write);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
&str);
string_write);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str);
if (timeoutSec)
curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT,
timeoutSec);
timeoutSec);
#if LIBCURL_VERSION_NUM >= 0x072400
// A lot of servers don't yet support ALPN
@ -86,7 +82,7 @@ void RemoteTextThread::run()
if (!postData.empty()) {
curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS,
postData.c_str());
postData.c_str());
}
code = curl_easy_perform(curl.get());
@ -101,7 +97,7 @@ void RemoteTextThread::run()
}
static size_t header_write(char *ptr, size_t size, size_t nmemb,
vector<string> &list)
vector<string> &list)
{
string str;
@ -118,16 +114,10 @@ static size_t header_write(char *ptr, size_t size, size_t nmemb,
return total;
}
bool GetRemoteFile(
const char *url,
std::string &str,
std::string &error,
long *responseCode,
const char *contentType,
const char *postData,
std::vector<std::string> extraHeaders,
std::string *signature,
int timeoutSec)
bool GetRemoteFile(const char *url, std::string &str, std::string &error,
long *responseCode, const char *contentType,
const char *postData, std::vector<std::string> extraHeaders,
std::string *signature, int timeoutSec)
{
vector<string> header_in_list;
char error_in[CURL_ERROR_SIZE];
@ -148,12 +138,11 @@ bool GetRemoteFile(
if (curl) {
struct curl_slist *header = nullptr;
header = curl_slist_append(header,
versionString.c_str());
header = curl_slist_append(header, versionString.c_str());
if (!contentTypeString.empty()) {
header = curl_slist_append(header,
contentTypeString.c_str());
contentTypeString.c_str());
}
for (std::string &h : extraHeaders)
@ -161,24 +150,21 @@ bool GetRemoteFile(
curl_easy_setopt(curl.get(), CURLOPT_URL, url);
curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, "");
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER,
header);
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER,
error_in);
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header);
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error_in);
curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION,
string_write);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
&str);
string_write);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str);
if (signature) {
curl_easy_setopt(curl.get(), CURLOPT_HEADERFUNCTION,
header_write);
header_write);
curl_easy_setopt(curl.get(), CURLOPT_HEADERDATA,
&header_in_list);
&header_in_list);
}
if (timeoutSec)
curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT,
timeoutSec);
timeoutSec);
#if LIBCURL_VERSION_NUM >= 0x072400
// A lot of servers don't yet support ALPN
@ -187,13 +173,13 @@ bool GetRemoteFile(
if (postData) {
curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS,
postData);
postData);
}
code = curl_easy_perform(curl.get());
if (responseCode)
curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE,
responseCode);
responseCode);
if (code != CURLE_OK) {
error = error_in;

View File

@ -38,38 +38,34 @@ signals:
void Result(const QString &text, const QString &error);
public:
inline RemoteTextThread(
std::string url_,
std::string contentType_ = std::string(),
std::string postData_ = std::string(),
int timeoutSec_ = 0)
: url (url_),
contentType (contentType_),
postData (postData_),
timeoutSec (timeoutSec_)
{}
inline RemoteTextThread(std::string url_,
std::string contentType_ = std::string(),
std::string postData_ = std::string(),
int timeoutSec_ = 0)
: url(url_),
contentType(contentType_),
postData(postData_),
timeoutSec(timeoutSec_)
{
}
inline RemoteTextThread(
std::string url_,
std::vector<std::string> &&extraHeaders_,
std::string contentType_ = std::string(),
std::string postData_ = std::string(),
int timeoutSec_ = 0)
: url (url_),
contentType (contentType_),
postData (postData_),
extraHeaders (std::move(extraHeaders_)),
timeoutSec (timeoutSec_)
{}
inline RemoteTextThread(std::string url_,
std::vector<std::string> &&extraHeaders_,
std::string contentType_ = std::string(),
std::string postData_ = std::string(),
int timeoutSec_ = 0)
: url(url_),
contentType(contentType_),
postData(postData_),
extraHeaders(std::move(extraHeaders_)),
timeoutSec(timeoutSec_)
{
}
};
bool GetRemoteFile(
const char *url,
std::string &str,
std::string &error,
long *responseCode = nullptr,
const char *contentType = nullptr,
const char *url, std::string &str, std::string &error,
long *responseCode = nullptr, const char *contentType = nullptr,
const char *postData = nullptr,
std::vector<std::string> extraHeaders = std::vector<std::string>(),
std::string *signature = nullptr,
int timeoutSec = 0);
std::string *signature = nullptr, int timeoutSec = 0);

View File

@ -1,19 +1,20 @@
#include "slider-absoluteset-style.hpp"
SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(const QString& baseStyle)
:QProxyStyle(baseStyle)
SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(const QString &baseStyle)
: QProxyStyle(baseStyle)
{
}
SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(QStyle* baseStyle)
:QProxyStyle(baseStyle)
SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(QStyle *baseStyle)
: QProxyStyle(baseStyle)
{
}
int SliderAbsoluteSetStyle::styleHint(QStyle::StyleHint hint,
const QStyleOption* option = 0, const QWidget* widget = 0,
QStyleHintReturn* returnData = 0) const
const QStyleOption *option = 0,
const QWidget *widget = 0,
QStyleHintReturn *returnData = 0) const
{
if(hint == QStyle::SH_Slider_AbsoluteSetButtons)
if (hint == QStyle::SH_Slider_AbsoluteSetButtons)
return (Qt::LeftButton | Qt::MidButton);
return QProxyStyle::styleHint(hint, option, widget, returnData);
}

View File

@ -2,11 +2,11 @@
#include <QProxyStyle>
class SliderAbsoluteSetStyle : public QProxyStyle
{
class SliderAbsoluteSetStyle : public QProxyStyle {
public:
SliderAbsoluteSetStyle(const QString& baseStyle);
SliderAbsoluteSetStyle(QStyle* baseStyle = Q_NULLPTR);
int styleHint(QStyle::StyleHint hint, const QStyleOption* option,
const QWidget* widget, QStyleHintReturn* returnData) const;
SliderAbsoluteSetStyle(const QString &baseStyle);
SliderAbsoluteSetStyle(QStyle *baseStyle = Q_NULLPTR);
int styleHint(QStyle::StyleHint hint, const QStyleOption *option,
const QWidget *widget,
QStyleHintReturn *returnData) const;
};

View File

@ -6,7 +6,7 @@ SliderIgnoreScroll::SliderIgnoreScroll(QWidget *parent) : QSlider(parent)
}
SliderIgnoreScroll::SliderIgnoreScroll(Qt::Orientation orientation,
QWidget *parent)
QWidget *parent)
: QSlider(parent)
{
setFocusPolicy(Qt::StrongFocus);

View File

@ -9,7 +9,8 @@ class SliderIgnoreScroll : public QSlider {
public:
SliderIgnoreScroll(QWidget *parent = nullptr);
SliderIgnoreScroll(Qt::Orientation orientation, QWidget *parent = nullptr);
SliderIgnoreScroll(Qt::Orientation orientation,
QWidget *parent = nullptr);
protected:
virtual void wheelEvent(QWheelEvent *event) override;

View File

@ -19,7 +19,7 @@
void OBSSourceLabel::SourceRenamed(void *data, calldata_t *params)
{
auto &label = *static_cast<OBSSourceLabel*>(data);
auto &label = *static_cast<OBSSourceLabel *>(data);
const char *name = calldata_string(params, "new_name");
label.setText(name);
@ -29,13 +29,13 @@ void OBSSourceLabel::SourceRenamed(void *data, calldata_t *params)
void OBSSourceLabel::SourceRemoved(void *data, calldata_t *)
{
auto &label = *static_cast<OBSSourceLabel*>(data);
auto &label = *static_cast<OBSSourceLabel *>(data);
emit label.Removed();
}
void OBSSourceLabel::SourceDestroyed(void *data, calldata_t *)
{
auto &label = *static_cast<OBSSourceLabel*>(data);
auto &label = *static_cast<OBSSourceLabel *>(data);
emit label.Destroyed();
label.destroyedSignal.Disconnect();

View File

@ -28,17 +28,18 @@ public:
OBSSignal removedSignal;
OBSSignal destroyedSignal;
OBSSourceLabel(const obs_source_t *source, QWidget *parent=nullptr,
Qt::WindowFlags f=0)
OBSSourceLabel(const obs_source_t *source, QWidget *parent = nullptr,
Qt::WindowFlags f = 0)
: QLabel(obs_source_get_name(source), parent, f),
renamedSignal(obs_source_get_signal_handler(source), "rename",
&OBSSourceLabel::SourceRenamed, this),
&OBSSourceLabel::SourceRenamed, this),
removedSignal(obs_source_get_signal_handler(source), "remove",
&OBSSourceLabel::SourceRemoved, this),
&OBSSourceLabel::SourceRemoved, this),
destroyedSignal(obs_source_get_signal_handler(source),
"destroy", &OBSSourceLabel::SourceDestroyed,
this)
{}
{
}
protected:
static void SourceRenamed(void *data, calldata_t *params);

View File

@ -25,15 +25,14 @@
static inline OBSScene GetCurrentScene()
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
return main->GetCurrentScene();
}
/* ========================================================================= */
SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
: tree (tree_),
sceneitem (sceneitem_)
: tree(tree_), sceneitem(sceneitem_)
{
setAttribute(Qt::WA_TranslucentBackground);
setMouseTracking(true);
@ -98,14 +97,12 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
/* --------------------------------------------------------- */
auto setItemVisible = [this] (bool checked)
{
auto setItemVisible = [this](bool checked) {
SignalBlocker sourcesSignalBlocker(this);
obs_sceneitem_set_visible(sceneitem, checked);
};
auto setItemLocked = [this] (bool checked)
{
auto setItemLocked = [this](bool checked) {
SignalBlocker sourcesSignalBlocker(this);
obs_sceneitem_set_locked(sceneitem, checked);
};
@ -150,59 +147,58 @@ void SourceTreeItem::ReconnectSignals()
/* --------------------------------------------------------- */
auto removeItem = [] (void *data, calldata_t *cd)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto removeItem = [](void *data, calldata_t *cd) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
obs_sceneitem_t *curItem =
(obs_sceneitem_t*)calldata_ptr(cd, "item");
(obs_sceneitem_t *)calldata_ptr(cd, "item");
if (curItem == this_->sceneitem) {
QMetaObject::invokeMethod(this_->tree,
"Remove",
Q_ARG(OBSSceneItem, curItem));
QMetaObject::invokeMethod(this_->tree, "Remove",
Q_ARG(OBSSceneItem, curItem));
curItem = nullptr;
}
if (!curItem)
QMetaObject::invokeMethod(this_, "Clear");
};
auto itemVisible = [] (void *data, calldata_t *cd)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto itemVisible = [](void *data, calldata_t *cd) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
obs_sceneitem_t *curItem =
(obs_sceneitem_t*)calldata_ptr(cd, "item");
(obs_sceneitem_t *)calldata_ptr(cd, "item");
bool visible = calldata_bool(cd, "visible");
if (curItem == this_->sceneitem)
QMetaObject::invokeMethod(this_, "VisibilityChanged",
Q_ARG(bool, visible));
Q_ARG(bool, visible));
};
auto itemLocked = [] (void *data, calldata_t *cd)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto itemLocked = [](void *data, calldata_t *cd) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
obs_sceneitem_t *curItem =
(obs_sceneitem_t*)calldata_ptr(cd, "item");
(obs_sceneitem_t *)calldata_ptr(cd, "item");
bool locked = calldata_bool(cd, "locked");
if (curItem == this_->sceneitem)
QMetaObject::invokeMethod(this_, "LockedChanged",
Q_ARG(bool, locked));
Q_ARG(bool, locked));
};
auto itemDeselect = [] (void *data, calldata_t *cd)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto itemDeselect = [](void *data, calldata_t *cd) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
obs_sceneitem_t *curItem =
(obs_sceneitem_t*)calldata_ptr(cd, "item");
(obs_sceneitem_t *)calldata_ptr(cd, "item");
if (curItem == this_->sceneitem)
QMetaObject::invokeMethod(this_, "Deselect");
};
auto reorderGroup = [] (void *data, calldata_t*)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto reorderGroup = [](void *data, calldata_t *) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
QMetaObject::invokeMethod(this_->tree, "ReorderItems");
};
@ -220,27 +216,27 @@ void SourceTreeItem::ReconnectSignals()
signal = obs_source_get_signal_handler(source);
groupReorderSignal.Connect(signal, "reorder", reorderGroup,
this);
this);
}
if (scene != GetCurrentScene())
deselectSignal.Connect(signal, "item_deselect", itemDeselect,
this);
this);
/* --------------------------------------------------------- */
auto renamed = [] (void *data, calldata_t *cd)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto renamed = [](void *data, calldata_t *cd) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
const char *name = calldata_string(cd, "new_name");
QMetaObject::invokeMethod(this_, "Renamed",
Q_ARG(QString, QT_UTF8(name)));
Q_ARG(QString, QT_UTF8(name)));
};
auto removeSource = [] (void *data, calldata_t *)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto removeSource = [](void *data, calldata_t *) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
this_->DisconnectSignals();
this_->sceneitem = nullptr;
};
@ -260,7 +256,7 @@ void SourceTreeItem::mouseDoubleClickEvent(QMouseEvent *event)
} else {
obs_source_t *source = obs_sceneitem_get_source(sceneitem);
OBSBasic *main =
reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
if (source) {
main->CreatePropertiesWindow(source);
}
@ -289,7 +285,7 @@ void SourceTreeItem::ExitEditMode(bool save)
if (!editor)
return;
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
std::string newName = QT_TO_UTF8(editor->text());
@ -308,9 +304,8 @@ void SourceTreeItem::ExitEditMode(bool save)
return;
if (newName.empty()) {
OBSMessageBox::information(main,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
OBSMessageBox::information(main, QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
return;
}
@ -324,15 +319,13 @@ void SourceTreeItem::ExitEditMode(bool save)
/* ----------------------------------------- */
/* check for existing source */
obs_source_t *existingSource =
obs_get_source_by_name(newName.c_str());
obs_source_t *existingSource = obs_get_source_by_name(newName.c_str());
obs_source_release(existingSource);
bool exists = !!existingSource;
if (exists) {
OBSMessageBox::information(main,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
OBSMessageBox::information(main, QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
return;
}
@ -355,22 +348,22 @@ bool SourceTreeItem::eventFilter(QObject *object, QEvent *event)
switch (keyEvent->key()) {
case Qt::Key_Escape:
QMetaObject::invokeMethod(this, "ExitEditMode",
Qt::QueuedConnection,
Q_ARG(bool, false));
Qt::QueuedConnection,
Q_ARG(bool, false));
return true;
case Qt::Key_Tab:
case Qt::Key_Backtab:
case Qt::Key_Enter:
case Qt::Key_Return:
QMetaObject::invokeMethod(this, "ExitEditMode",
Qt::QueuedConnection,
Q_ARG(bool, true));
Qt::QueuedConnection,
Q_ARG(bool, true));
return true;
}
} else if (event->type() == QEvent::FocusOut) {
QMetaObject::invokeMethod(this, "ExitEditMode",
Qt::QueuedConnection,
Q_ARG(bool, true));
Qt::QueuedConnection,
Q_ARG(bool, true));
return true;
}
@ -405,14 +398,14 @@ void SourceTreeItem::Update(bool force)
if (obs_sceneitem_is_group(sceneitem)) {
newType = Type::Group;
/* ------------------------------------------------- */
/* if it's a group sub-item */
/* ------------------------------------------------- */
/* if it's a group sub-item */
} else if (itemScene != scene) {
newType = Type::SubItem;
/* ------------------------------------------------- */
/* if it's a regular item */
/* ------------------------------------------------- */
/* if it's a regular item */
} else {
newType = Type::Item;
@ -448,9 +441,8 @@ void SourceTreeItem::Update(bool force)
} else if (type == Type::Group) {
expand = new SourceTreeSubItemCheckBox();
expand->setSizePolicy(
QSizePolicy::Maximum,
QSizePolicy::Maximum);
expand->setSizePolicy(QSizePolicy::Maximum,
QSizePolicy::Maximum);
expand->setMaximumSize(10, 16);
expand->setMinimumSize(10, 0);
#ifdef __APPLE__
@ -458,14 +450,15 @@ void SourceTreeItem::Update(bool force)
#endif
boxLayout->insertWidget(0, expand);
obs_data_t *data = obs_sceneitem_get_private_settings(sceneitem);
obs_data_t *data =
obs_sceneitem_get_private_settings(sceneitem);
expand->blockSignals(true);
expand->setChecked(obs_data_get_bool(data, "collapsed"));
expand->blockSignals(false);
obs_data_release(data);
connect(expand, &QPushButton::toggled,
this, &SourceTreeItem::ExpandClicked);
connect(expand, &QPushButton::toggled, this,
&SourceTreeItem::ExpandClicked);
} else {
spacer = new QSpacerItem(3, 1);
@ -517,10 +510,10 @@ void SourceTreeModel::Clear()
hasGroups = false;
}
static bool enumItem(obs_scene_t*, obs_sceneitem_t *item, void *ptr)
static bool enumItem(obs_scene_t *, obs_sceneitem_t *item, void *ptr)
{
QVector<OBSSceneItem> &items =
*reinterpret_cast<QVector<OBSSceneItem>*>(ptr);
*reinterpret_cast<QVector<OBSSceneItem> *>(ptr);
if (obs_sceneitem_is_group(item)) {
obs_data_t *data = obs_sceneitem_get_private_settings(item);
@ -556,14 +549,15 @@ void SourceTreeModel::SceneChanged()
bool select = obs_sceneitem_selected(items[i]);
QModelIndex index = createIndex(i, 0);
st->selectionModel()->select(index, select
? QItemSelectionModel::Select
: QItemSelectionModel::Deselect);
st->selectionModel()->select(
index, select ? QItemSelectionModel::Select
: QItemSelectionModel::Deselect);
}
}
/* moves a scene item index (blame linux distros for using older Qt builds) */
static inline void MoveItem(QVector<OBSSceneItem> &items, int oldIdx, int newIdx)
static inline void MoveItem(QVector<OBSSceneItem> &items, int oldIdx,
int newIdx)
{
OBSSceneItem item = items[oldIdx];
items.remove(oldIdx);
@ -637,7 +631,7 @@ void SourceTreeModel::ReorderItems()
/* move items */
beginMoveRows(QModelIndex(), idx1Old, idx1Old + count - 1,
QModelIndex(), idx1New + count);
QModelIndex(), idx1New + count);
for (i = 0; i < count; i++) {
int to = idx1New + count;
if (to > idx1Old)
@ -709,8 +703,7 @@ OBSSceneItem SourceTreeModel::Get(int idx)
}
SourceTreeModel::SourceTreeModel(SourceTree *st_)
: QAbstractListModel (st_),
st (st_)
: QAbstractListModel(st_), st(st_)
{
obs_frontend_add_event_callback(OBSFrontendEvent, this);
}
@ -744,8 +737,7 @@ Qt::ItemFlags SourceTreeModel::flags(const QModelIndex &index) const
obs_sceneitem_t *item = items[index.row()];
bool is_group = obs_sceneitem_is_group(item);
return QAbstractListModel::flags(index) |
Qt::ItemIsEditable |
return QAbstractListModel::flags(index) | Qt::ItemIsEditable |
Qt::ItemIsDragEnabled |
(is_group ? Qt::ItemIsDropEnabled : Qt::NoItemFlags);
}
@ -775,8 +767,8 @@ QString SourceTreeModel::GetNewGroupName()
void SourceTreeModel::AddGroup()
{
QString name = GetNewGroupName();
obs_sceneitem_t *group = obs_scene_add_group(GetCurrentScene(),
QT_TO_UTF8(name));
obs_sceneitem_t *group =
obs_scene_add_group(GetCurrentScene(), QT_TO_UTF8(name));
if (!group)
return;
@ -788,7 +780,7 @@ void SourceTreeModel::AddGroup()
UpdateGroupState(true);
QMetaObject::invokeMethod(st, "Edit", Qt::QueuedConnection,
Q_ARG(int, 0));
Q_ARG(int, 0));
}
void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
@ -807,8 +799,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
}
obs_sceneitem_t *item = obs_scene_insert_group(
scene, QT_TO_UTF8(name),
item_order.data(), item_order.size());
scene, QT_TO_UTF8(name), item_order.data(), item_order.size());
if (!item) {
return;
}
@ -827,7 +818,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
int toIdx = newIdx + i + 1;
if (fromIdx != toIdx) {
beginMoveRows(QModelIndex(), fromIdx, fromIdx,
QModelIndex(), toIdx);
QModelIndex(), toIdx);
MoveItem(items, fromIdx, toIdx);
endMoveRows();
}
@ -839,7 +830,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
obs_sceneitem_select(item, true);
QMetaObject::invokeMethod(st, "Edit", Qt::QueuedConnection,
Q_ARG(int, newIdx));
Q_ARG(int, newIdx));
}
void SourceTreeModel::UngroupSelectedGroups(QModelIndexList &indices)
@ -929,20 +920,20 @@ SourceTree::SourceTree(QWidget *parent_) : QListView(parent_)
SourceTreeModel *stm_ = new SourceTreeModel(this);
setModel(stm_);
setStyleSheet(QString(
"*[bgColor=\"1\"]{background-color:rgba(255,68,68,33%);}" \
"*[bgColor=\"2\"]{background-color:rgba(255,255,68,33%);}" \
"*[bgColor=\"3\"]{background-color:rgba(68,255,68,33%);}" \
"*[bgColor=\"4\"]{background-color:rgba(68,255,255,33%);}" \
"*[bgColor=\"5\"]{background-color:rgba(68,68,255,33%);}" \
"*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}" \
"*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}" \
"*[bgColor=\"1\"]{background-color:rgba(255,68,68,33%);}"
"*[bgColor=\"2\"]{background-color:rgba(255,255,68,33%);}"
"*[bgColor=\"3\"]{background-color:rgba(68,255,68,33%);}"
"*[bgColor=\"4\"]{background-color:rgba(68,255,255,33%);}"
"*[bgColor=\"5\"]{background-color:rgba(68,68,255,33%);}"
"*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}"
"*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}"
"*[bgColor=\"8\"]{background-color:rgba(255,255,255,33%);}"));
setMouseTracking(true);
UpdateNoSourcesMessage();
connect(App(), &OBSApp::StyleChanged,
this, &SourceTree::UpdateNoSourcesMessage);
connect(App(), &OBSApp::StyleChanged, this,
&SourceTree::UpdateNoSourcesMessage);
}
void SourceTree::ResetWidgets()
@ -994,9 +985,9 @@ void SourceTree::SelectItem(obs_sceneitem_t *sceneitem, bool select)
QModelIndex index = stm->createIndex(i, 0);
if (index.isValid())
selectionModel()->select(index, select
? QItemSelectionModel::Select
: QItemSelectionModel::Deselect);
selectionModel()->select(
index, select ? QItemSelectionModel::Select
: QItemSelectionModel::Deselect);
}
Q_DECLARE_METATYPE(OBSSceneItem);
@ -1040,9 +1031,9 @@ void SourceTree::dropEvent(QDropEvent *event)
obs_sceneitem_t *dropItem = items[row]; /* item being dropped on */
bool itemIsGroup = obs_sceneitem_is_group(dropItem);
obs_sceneitem_t *dropGroup = itemIsGroup
? dropItem
: obs_sceneitem_get_group(scene, dropItem);
obs_sceneitem_t *dropGroup =
itemIsGroup ? dropItem
: obs_sceneitem_get_group(scene, dropItem);
/* not a group if moving above the group */
if (indicator == QAbstractItemView::AboveItem && itemIsGroup)
@ -1056,7 +1047,8 @@ void SourceTree::dropEvent(QDropEvent *event)
bool dropOnCollapsed = false;
if (dropGroup) {
obs_data_t *data = obs_sceneitem_get_private_settings(dropGroup);
obs_data_t *data =
obs_sceneitem_get_private_settings(dropGroup);
dropOnCollapsed = obs_data_get_bool(data, "collapsed");
obs_data_release(data);
}
@ -1086,9 +1078,8 @@ void SourceTree::dropEvent(QDropEvent *event)
/* if dropping a group, detect if it's */
/* below another group */
obs_sceneitem_t *itemBelow = row == stm->items.count()
? nullptr
: stm->items[row];
obs_sceneitem_t *itemBelow =
row == stm->items.count() ? nullptr : stm->items[row];
if (hasGroups) {
if (!itemBelow ||
obs_sceneitem_get_group(scene, itemBelow) != dropGroup) {
@ -1131,8 +1122,8 @@ void SourceTree::dropEvent(QDropEvent *event)
for (int j = items.size() - 1; j >= 0; j--) {
obs_sceneitem_t *subitem = items[j];
obs_sceneitem_t *subitemGroup =
obs_sceneitem_get_group(scene,
subitem);
obs_sceneitem_get_group(
scene, subitem);
if (subitemGroup == item) {
QModelIndex idx =
@ -1167,7 +1158,7 @@ void SourceTree::dropEvent(QDropEvent *event)
if (itemTo != from) {
stm->beginMoveRows(QModelIndex(), from, from,
QModelIndex(), to);
QModelIndex(), to);
MoveItem(items, from, itemTo);
stm->endMoveRows();
}
@ -1186,8 +1177,7 @@ void SourceTree::dropEvent(QDropEvent *event)
obs_sceneitem_t *lastGroup = nullptr;
int insertCollapsedIdx = 0;
auto insertCollapsed = [&] (obs_sceneitem_t *item)
{
auto insertCollapsed = [&](obs_sceneitem_t *item) {
struct obs_sceneitem_order_info info;
info.group = lastGroup;
info.item = item;
@ -1197,25 +1187,23 @@ void SourceTree::dropEvent(QDropEvent *event)
using insertCollapsed_t = decltype(insertCollapsed);
auto preInsertCollapsed = [] (obs_scene_t *, obs_sceneitem_t *item,
void *param)
{
auto preInsertCollapsed = [](obs_scene_t *, obs_sceneitem_t *item,
void *param) {
(*reinterpret_cast<insertCollapsed_t *>(param))(item);
return true;
};
auto insertLastGroup = [&] ()
{
obs_data_t *data = obs_sceneitem_get_private_settings(lastGroup);
auto insertLastGroup = [&]() {
obs_data_t *data =
obs_sceneitem_get_private_settings(lastGroup);
bool collapsed = obs_data_get_bool(data, "collapsed");
obs_data_release(data);
if (collapsed) {
insertCollapsedIdx = 0;
obs_sceneitem_group_enum_items(
lastGroup,
preInsertCollapsed,
&insertCollapsed);
obs_sceneitem_group_enum_items(lastGroup,
preInsertCollapsed,
&insertCollapsed);
}
struct obs_sceneitem_order_info info;
@ -1224,8 +1212,7 @@ void SourceTree::dropEvent(QDropEvent *event)
orderList.insert(0, info);
};
auto updateScene = [&] ()
{
auto updateScene = [&]() {
struct obs_sceneitem_order_info info;
for (int i = 0; i < items.size(); i++) {
@ -1260,14 +1247,13 @@ void SourceTree::dropEvent(QDropEvent *event)
insertLastGroup();
}
obs_scene_reorder_items2(scene,
orderList.data(), orderList.size());
obs_scene_reorder_items2(scene, orderList.data(),
orderList.size());
};
using updateScene_t = decltype(updateScene);
auto preUpdateScene = [] (void *data, obs_scene_t *)
{
auto preUpdateScene = [](void *data, obs_scene_t *) {
(*reinterpret_cast<updateScene_t *>(data))();
};
@ -1314,9 +1300,8 @@ void SourceTree::leaveEvent(QEvent *event)
QListView::leaveEvent(event);
}
void SourceTree::selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected)
void SourceTree::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
{
SignalBlocker sourcesSignalBlocker(this);
@ -1425,7 +1410,7 @@ bool SourceTree::GroupedItemsSelected() const
void SourceTree::Remove(OBSSceneItem item)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
GetStm()->Remove(item);
main->SaveProject();
@ -1434,9 +1419,9 @@ void SourceTree::Remove(OBSSceneItem item)
obs_source_t *sceneSource = obs_scene_get_source(scene);
obs_source_t *itemSource = obs_sceneitem_get_source(item);
blog(LOG_INFO, "User Removed source '%s' (%s) from scene '%s'",
obs_source_get_name(itemSource),
obs_source_get_id(itemSource),
obs_source_get_name(sceneSource));
obs_source_get_name(itemSource),
obs_source_get_id(itemSource),
obs_source_get_name(sceneSource));
}
}
@ -1465,9 +1450,8 @@ void SourceTree::UpdateNoSourcesMessage()
QColor color = palette().text().color();
bool lightTheme = (color.redF() < 0.5);
QString file = lightTheme
? ":res/images/no_sources.svg"
: darkPath.c_str();
QString file = lightTheme ? ":res/images/no_sources.svg"
: darkPath.c_str();
iconNoSources.load(file);
QTextOption opt(Qt::AlignHCenter);

View File

@ -72,7 +72,7 @@ private:
OBSSignal renameSignal;
OBSSignal removeSignal;
virtual void paintEvent(QPaintEvent* event) override;
virtual void paintEvent(QPaintEvent *event) override;
private slots:
void Clear();
@ -123,7 +123,8 @@ public:
~SourceTreeModel();
virtual int rowCount(const QModelIndex &parent) const override;
virtual QVariant data(const QModelIndex &index, int role) const override;
virtual QVariant data(const QModelIndex &index,
int role) const override;
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
virtual Qt::DropActions supportedDropActions() const override;
@ -161,12 +162,12 @@ public:
explicit SourceTree(QWidget *parent = nullptr);
inline bool IgnoreReorder() const {return ignoreReorder;}
inline void Clear() {GetStm()->Clear();}
inline bool IgnoreReorder() const { return ignoreReorder; }
inline void Clear() { GetStm()->Clear(); }
inline void Add(obs_sceneitem_t *item) {GetStm()->Add(item);}
inline OBSSceneItem Get(int idx) {return GetStm()->Get(idx);}
inline QString GetNewGroupName() {return GetStm()->GetNewGroupName();}
inline void Add(obs_sceneitem_t *item) { GetStm()->Add(item); }
inline OBSSceneItem Get(int idx) { return GetStm()->Get(idx); }
inline QString GetNewGroupName() { return GetStm()->GetNewGroupName(); }
void SelectItem(obs_sceneitem_t *sceneitem, bool select);
@ -175,7 +176,7 @@ public:
bool GroupedItemsSelected() const;
public slots:
inline void ReorderItems() {GetStm()->ReorderItems();}
inline void ReorderItems() { GetStm()->ReorderItems(); }
void Remove(OBSSceneItem item);
void GroupSelectedItems();
void UngroupSelectedGroups();
@ -189,5 +190,7 @@ protected:
virtual void leaveEvent(QEvent *event) override;
virtual void paintEvent(QPaintEvent *event) override;
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override;
virtual void
selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected) override;
};

View File

@ -8,8 +8,7 @@ class VScrollArea : public QScrollArea {
Q_OBJECT
public:
inline VScrollArea(QWidget *parent = nullptr)
: QScrollArea(parent)
inline VScrollArea(QWidget *parent = nullptr) : QScrollArea(parent)
{
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

View File

@ -10,11 +10,11 @@
#include <QLabel>
VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
: source (source_),
enabledSignal (obs_source_get_signal_handler(source), "enable",
OBSSourceEnabled, this),
renamedSignal (obs_source_get_signal_handler(source), "rename",
OBSSourceRenamed, this)
: source(source_),
enabledSignal(obs_source_get_signal_handler(source), "enable",
OBSSourceEnabled, this),
renamedSignal(obs_source_get_signal_handler(source), "rename",
OBSSourceRenamed, this)
{
const char *name = obs_source_get_name(source);
bool enabled = obs_source_enabled(source);
@ -38,15 +38,15 @@ VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
setLayout(itemLayout);
setStyleSheet("background-color: rgba(255, 255, 255, 0);");
connect(vis, SIGNAL(clicked(bool)),
this, SLOT(VisibilityClicked(bool)));
connect(vis, SIGNAL(clicked(bool)), this,
SLOT(VisibilityClicked(bool)));
}
VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
: item (item_),
source (obs_sceneitem_get_source(item)),
renamedSignal (obs_source_get_signal_handler(source), "rename",
OBSSourceRenamed, this)
: item(item_),
source(obs_sceneitem_get_source(item)),
renamedSignal(obs_source_get_signal_handler(source), "rename",
OBSSourceRenamed, this)
{
const char *name = obs_source_get_name(source);
bool enabled = obs_sceneitem_visible(item);
@ -90,18 +90,15 @@ VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
signal_handler_t *signal = obs_source_get_signal_handler(sceneSource);
signal_handler_connect(signal, "remove", OBSSceneRemove, this);
signal_handler_connect(signal, "item_remove", OBSSceneItemRemove,
this);
signal_handler_connect(signal, "item_remove", OBSSceneItemRemove, this);
signal_handler_connect(signal, "item_visible", OBSSceneItemVisible,
this);
signal_handler_connect(signal, "item_locked", OBSSceneItemLocked,
this);
this);
signal_handler_connect(signal, "item_locked", OBSSceneItemLocked, this);
connect(vis, SIGNAL(clicked(bool)),
this, SLOT(VisibilityClicked(bool)));
connect(vis, SIGNAL(clicked(bool)), this,
SLOT(VisibilityClicked(bool)));
connect(lock, SIGNAL(clicked(bool)),
this, SLOT(LockClicked(bool)));
connect(lock, SIGNAL(clicked(bool)), this, SLOT(LockClicked(bool)));
}
VisibilityItemWidget::~VisibilityItemWidget()
@ -120,11 +117,11 @@ void VisibilityItemWidget::DisconnectItemSignals()
signal_handler_disconnect(signal, "remove", OBSSceneRemove, this);
signal_handler_disconnect(signal, "item_remove", OBSSceneItemRemove,
this);
this);
signal_handler_disconnect(signal, "item_visible", OBSSceneItemVisible,
this);
this);
signal_handler_disconnect(signal, "item_locked", OBSSceneItemLocked,
this);
this);
sceneRemoved = true;
}
@ -132,7 +129,7 @@ void VisibilityItemWidget::DisconnectItemSignals()
void VisibilityItemWidget::OBSSceneRemove(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
reinterpret_cast<VisibilityItemWidget *>(param);
window->DisconnectItemSignals();
@ -142,8 +139,8 @@ void VisibilityItemWidget::OBSSceneRemove(void *param, calldata_t *data)
void VisibilityItemWidget::OBSSceneItemRemove(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(data, "item");
reinterpret_cast<VisibilityItemWidget *>(param);
obs_sceneitem_t *item = (obs_sceneitem_t *)calldata_ptr(data, "item");
if (item == window->item)
window->DisconnectItemSignals();
@ -152,45 +149,47 @@ void VisibilityItemWidget::OBSSceneItemRemove(void *param, calldata_t *data)
void VisibilityItemWidget::OBSSceneItemVisible(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
obs_sceneitem_t *curItem = (obs_sceneitem_t*)calldata_ptr(data, "item");
reinterpret_cast<VisibilityItemWidget *>(param);
obs_sceneitem_t *curItem =
(obs_sceneitem_t *)calldata_ptr(data, "item");
bool enabled = calldata_bool(data, "visible");
if (window->item == curItem)
QMetaObject::invokeMethod(window, "SourceEnabled",
Q_ARG(bool, enabled));
Q_ARG(bool, enabled));
}
void VisibilityItemWidget::OBSSceneItemLocked(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
obs_sceneitem_t *curItem = (obs_sceneitem_t*)calldata_ptr(data, "item");
reinterpret_cast<VisibilityItemWidget *>(param);
obs_sceneitem_t *curItem =
(obs_sceneitem_t *)calldata_ptr(data, "item");
bool locked = calldata_bool(data, "locked");
if (window->item == curItem)
QMetaObject::invokeMethod(window, "SourceLocked",
Q_ARG(bool, locked));
Q_ARG(bool, locked));
}
void VisibilityItemWidget::OBSSourceEnabled(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
reinterpret_cast<VisibilityItemWidget *>(param);
bool enabled = calldata_bool(data, "enabled");
QMetaObject::invokeMethod(window, "SourceEnabled",
Q_ARG(bool, enabled));
Q_ARG(bool, enabled));
}
void VisibilityItemWidget::OBSSourceRenamed(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
reinterpret_cast<VisibilityItemWidget *>(param);
const char *name = calldata_string(data, "new_name");
QMetaObject::invokeMethod(window, "SourceRenamed",
Q_ARG(QString, QT_UTF8(name)));
Q_ARG(QString, QT_UTF8(name)));
}
void VisibilityItemWidget::VisibilityClicked(bool visible)
@ -225,8 +224,8 @@ void VisibilityItemWidget::SourceRenamed(QString name)
label->setText(name);
}
void VisibilityItemWidget::SetColor(const QColor &color,
bool active_, bool selected_)
void VisibilityItemWidget::SetColor(const QColor &color, bool active_,
bool selected_)
{
/* Do not update unless the state has actually changed */
if (active_ == active && selected_ == selected)
@ -248,19 +247,19 @@ VisibilityItemDelegate::VisibilityItemDelegate(QObject *parent)
}
void VisibilityItemDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QStyledItemDelegate::paint(painter, option, index);
QObject *parentObj = parent();
QListWidget *list = qobject_cast<QListWidget*>(parentObj);
QListWidget *list = qobject_cast<QListWidget *>(parentObj);
if (!list)
return;
QListWidgetItem *item = list->item(index.row());
VisibilityItemWidget *widget =
qobject_cast<VisibilityItemWidget*>(list->itemWidget(item));
qobject_cast<VisibilityItemWidget *>(list->itemWidget(item));
if (!widget)
return;
@ -269,8 +268,8 @@ void VisibilityItemDelegate::paint(QPainter *painter,
QPalette palette = list->palette();
#if defined(_WIN32) || defined(__APPLE__)
QPalette::ColorGroup group = active ?
QPalette::Active : QPalette::Inactive;
QPalette::ColorGroup group = active ? QPalette::Active
: QPalette::Inactive;
#else
QPalette::ColorGroup group = QPalette::Active;
#endif
@ -292,7 +291,7 @@ void VisibilityItemDelegate::paint(QPainter *painter,
}
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
obs_source_t *source)
obs_source_t *source)
{
VisibilityItemWidget *baseWidget = new VisibilityItemWidget(source);
@ -301,7 +300,7 @@ void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
}
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
obs_sceneitem_t *sceneItem)
obs_sceneitem_t *sceneItem)
{
VisibilityItemWidget *baseWidget = new VisibilityItemWidget(sceneItem);

View File

@ -61,10 +61,10 @@ public:
VisibilityItemDelegate(QObject *parent = nullptr);
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
const QModelIndex &index) const override;
};
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
obs_source_t *source);
obs_source_t *source);
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
obs_sceneitem_t *sceneItem);
obs_sceneitem_t *sceneItem);

View File

@ -21,35 +21,35 @@ QWeakPointer<VolumeMeterTimer> VolumeMeter::updateTimer;
void VolControl::OBSVolumeChanged(void *data, float db)
{
Q_UNUSED(db);
VolControl *volControl = static_cast<VolControl*>(data);
VolControl *volControl = static_cast<VolControl *>(data);
QMetaObject::invokeMethod(volControl, "VolumeChanged");
}
void VolControl::OBSVolumeLevel(void *data,
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS])
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS])
{
VolControl *volControl = static_cast<VolControl*>(data);
VolControl *volControl = static_cast<VolControl *>(data);
volControl->volMeter->setLevels(magnitude, peak, inputPeak);
}
void VolControl::OBSVolumeMuted(void *data, calldata_t *calldata)
{
VolControl *volControl = static_cast<VolControl*>(data);
VolControl *volControl = static_cast<VolControl *>(data);
bool muted = calldata_bool(calldata, "muted");
QMetaObject::invokeMethod(volControl, "VolumeMuted",
Q_ARG(bool, muted));
Q_ARG(bool, muted));
}
void VolControl::VolumeChanged()
{
slider->blockSignals(true);
slider->setValue((int) (obs_fader_get_deflection(obs_fader) *
FADER_PRECISION));
slider->setValue(
(int)(obs_fader_get_deflection(obs_fader) * FADER_PRECISION));
slider->blockSignals(false);
updateText();
@ -75,13 +75,12 @@ void VolControl::SliderChanged(int vol)
void VolControl::updateText()
{
QString db = QString::number(obs_fader_get_db(obs_fader), 'f', 1)
.append(" dB");
.append(" dB");
volLabel->setText(db);
bool muted = obs_source_muted(source);
const char *accTextLookup = muted
? "VolControl.SliderMuted"
: "VolControl.SliderUnmuted";
const char *accTextLookup = muted ? "VolControl.SliderMuted"
: "VolControl.SliderUnmuted";
QString sourceName = obs_source_get_name(source);
QString accText = QTStr(accTextLookup).arg(sourceName, db);
@ -115,16 +114,16 @@ void VolControl::setPeakMeterType(enum obs_peak_meter_type peakMeterType)
}
VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
: source (std::move(source_)),
levelTotal (0.0f),
levelCount (0.0f),
obs_fader (obs_fader_create(OBS_FADER_LOG)),
obs_volmeter (obs_volmeter_create(OBS_FADER_LOG)),
vertical (vertical)
: source(std::move(source_)),
levelTotal(0.0f),
levelCount(0.0f),
obs_fader(obs_fader_create(OBS_FADER_LOG)),
obs_volmeter(obs_volmeter_create(OBS_FADER_LOG)),
vertical(vertical)
{
nameLabel = new QLabel();
volLabel = new QLabel();
mute = new MuteCheckBox();
volLabel = new QLabel();
mute = new MuteCheckBox();
QString sourceName = obs_source_get_name(source);
setObjectName(sourceName);
@ -134,15 +133,15 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
config->setProperty("themeID", "configIconSmall");
config->setFlat(true);
config->setSizePolicy(QSizePolicy::Maximum,
QSizePolicy::Maximum);
QSizePolicy::Maximum);
config->setMaximumSize(22, 22);
config->setAutoDefault(false);
config->setAccessibleName(QTStr("VolControl.Properties")
.arg(sourceName));
config->setAccessibleName(
QTStr("VolControl.Properties").arg(sourceName));
connect(config, &QAbstractButton::clicked,
this, &VolControl::EmitConfigClicked);
connect(config, &QAbstractButton::clicked, this,
&VolControl::EmitConfigClicked);
}
QVBoxLayout *mainLayout = new QVBoxLayout;
@ -153,10 +152,10 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
QHBoxLayout *nameLayout = new QHBoxLayout;
QHBoxLayout *controlLayout = new QHBoxLayout;
QHBoxLayout *volLayout = new QHBoxLayout;
QHBoxLayout *meterLayout = new QHBoxLayout;
QHBoxLayout *meterLayout = new QHBoxLayout;
volMeter = new VolumeMeter(nullptr, obs_volmeter, true);
slider = new SliderIgnoreScroll(Qt::Vertical);
volMeter = new VolumeMeter(nullptr, obs_volmeter, true);
slider = new SliderIgnoreScroll(Qt::Vertical);
nameLayout->setAlignment(Qt::AlignCenter);
meterLayout->setAlignment(Qt::AlignCenter);
@ -195,18 +194,18 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
setMaximumWidth(110);
} else {
QHBoxLayout *volLayout = new QHBoxLayout;
QHBoxLayout *volLayout = new QHBoxLayout;
QHBoxLayout *textLayout = new QHBoxLayout;
QHBoxLayout *botLayout = new QHBoxLayout;
QHBoxLayout *botLayout = new QHBoxLayout;
volMeter = new VolumeMeter(nullptr, obs_volmeter, false);
slider = new SliderIgnoreScroll(Qt::Horizontal);
volMeter = new VolumeMeter(nullptr, obs_volmeter, false);
slider = new SliderIgnoreScroll(Qt::Horizontal);
textLayout->setContentsMargins(0, 0, 0, 0);
textLayout->addWidget(nameLabel);
textLayout->addWidget(volLabel);
textLayout->setAlignment(nameLabel, Qt::AlignLeft);
textLayout->setAlignment(volLabel, Qt::AlignRight);
textLayout->setAlignment(volLabel, Qt::AlignRight);
volLayout->addWidget(slider);
volLayout->addWidget(mute);
@ -229,7 +228,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
setLayout(mainLayout);
QFont font = nameLabel->font();
font.setPointSize(font.pointSize()-1);
font.setPointSize(font.pointSize() - 1);
nameLabel->setText(sourceName);
nameLabel->setFont(font);
@ -244,13 +243,13 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
obs_fader_add_callback(obs_fader, OBSVolumeChanged, this);
obs_volmeter_add_callback(obs_volmeter, OBSVolumeLevel, this);
signal_handler_connect(obs_source_get_signal_handler(source),
"mute", OBSVolumeMuted, this);
signal_handler_connect(obs_source_get_signal_handler(source), "mute",
OBSVolumeMuted, this);
QWidget::connect(slider, SIGNAL(valueChanged(int)),
this, SLOT(SliderChanged(int)));
QWidget::connect(mute, SIGNAL(clicked(bool)),
this, SLOT(SetMuted(bool)));
QWidget::connect(slider, SIGNAL(valueChanged(int)), this,
SLOT(SliderChanged(int)));
QWidget::connect(mute, SIGNAL(clicked(bool)), this,
SLOT(SetMuted(bool)));
obs_fader_attach_source(obs_fader, source);
obs_volmeter_attach_source(obs_volmeter, source);
@ -276,8 +275,8 @@ VolControl::~VolControl()
obs_fader_remove_callback(obs_fader, OBSVolumeChanged, this);
obs_volmeter_remove_callback(obs_volmeter, OBSVolumeLevel, this);
signal_handler_disconnect(obs_source_get_signal_handler(source),
"mute", OBSVolumeMuted, this);
signal_handler_disconnect(obs_source_get_signal_handler(source), "mute",
OBSVolumeMuted, this);
obs_fader_destroy(obs_fader);
obs_volmeter_destroy(obs_volmeter);
@ -517,34 +516,33 @@ void VolumeMeter::wheelEvent(QWheelEvent *event)
}
VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter,
bool vertical)
: QWidget(parent), obs_volmeter(obs_volmeter),
vertical(vertical)
bool vertical)
: QWidget(parent), obs_volmeter(obs_volmeter), vertical(vertical)
{
// Use a font that can be rendered small.
tickFont = QFont("Arial");
tickFont.setPixelSize(7);
// Default meter color settings, they only show if
// there is no stylesheet, do not remove.
backgroundNominalColor.setRgb(0x26, 0x7f, 0x26); // Dark green
backgroundWarningColor.setRgb(0x7f, 0x7f, 0x26); // Dark yellow
backgroundErrorColor.setRgb(0x7f, 0x26, 0x26); // Dark red
foregroundNominalColor.setRgb(0x4c, 0xff, 0x4c); // Bright green
foregroundWarningColor.setRgb(0xff, 0xff, 0x4c); // Bright yellow
foregroundErrorColor.setRgb(0xff, 0x4c, 0x4c); // Bright red
clipColor.setRgb(0xff, 0xff, 0xff); // Bright white
magnitudeColor.setRgb(0x00, 0x00, 0x00); // Black
majorTickColor.setRgb(0xff, 0xff, 0xff); // Black
minorTickColor.setRgb(0xcc, 0xcc, 0xcc); // Black
minimumLevel = -60.0; // -60 dB
warningLevel = -20.0; // -20 dB
errorLevel = -9.0; // -9 dB
clipLevel = -0.5; // -0.5 dB
minimumInputLevel = -50.0; // -50 dB
peakDecayRate = 11.76; // 20 dB / 1.7 sec
magnitudeIntegrationTime = 0.3; // 99% in 300 ms
peakHoldDuration = 20.0; // 20 seconds
inputPeakHoldDuration = 1.0; // 1 second
backgroundNominalColor.setRgb(0x26, 0x7f, 0x26); // Dark green
backgroundWarningColor.setRgb(0x7f, 0x7f, 0x26); // Dark yellow
backgroundErrorColor.setRgb(0x7f, 0x26, 0x26); // Dark red
foregroundNominalColor.setRgb(0x4c, 0xff, 0x4c); // Bright green
foregroundWarningColor.setRgb(0xff, 0xff, 0x4c); // Bright yellow
foregroundErrorColor.setRgb(0xff, 0x4c, 0x4c); // Bright red
clipColor.setRgb(0xff, 0xff, 0xff); // Bright white
magnitudeColor.setRgb(0x00, 0x00, 0x00); // Black
majorTickColor.setRgb(0xff, 0xff, 0xff); // Black
minorTickColor.setRgb(0xcc, 0xcc, 0xcc); // Black
minimumLevel = -60.0; // -60 dB
warningLevel = -20.0; // -20 dB
errorLevel = -9.0; // -9 dB
clipLevel = -0.5; // -0.5 dB
minimumInputLevel = -50.0; // -50 dB
peakDecayRate = 11.76; // 20 dB / 1.7 sec
magnitudeIntegrationTime = 0.3; // 99% in 300 ms
peakHoldDuration = 20.0; // 20 seconds
inputPeakHoldDuration = 1.0; // 1 second
channels = (int)audio_output_get_channels(obs_get_audio());
@ -566,8 +564,8 @@ VolumeMeter::~VolumeMeter()
}
void VolumeMeter::setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS])
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS])
{
uint64_t ts = os_gettime_ns();
QMutexLocker locker(&dataMutex);
@ -632,11 +630,12 @@ inline bool VolumeMeter::detectIdle(uint64_t ts)
}
}
inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
uint64_t ts, qreal timeSinceLastRedraw)
inline void
VolumeMeter::calculateBallisticsForChannel(int channelNr, uint64_t ts,
qreal timeSinceLastRedraw)
{
if (currentPeak[channelNr] >= displayPeak[channelNr] ||
isnan(displayPeak[channelNr])) {
isnan(displayPeak[channelNr])) {
// Attack of peak is immediate.
displayPeak[channelNr] = currentPeak[channelNr];
} else {
@ -645,11 +644,11 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
// 24 dB / 2.8 seconds for Slow Profile (Type II PPM)
float decay = float(peakDecayRate * timeSinceLastRedraw);
displayPeak[channelNr] = CLAMP(displayPeak[channelNr] - decay,
currentPeak[channelNr], 0);
currentPeak[channelNr], 0);
}
if (currentPeak[channelNr] >= displayPeakHold[channelNr] ||
!isfinite(displayPeakHold[channelNr])) {
!isfinite(displayPeakHold[channelNr])) {
// Attack of peak-hold is immediate, but keep track
// when it was last updated.
displayPeakHold[channelNr] = currentPeak[channelNr];
@ -657,8 +656,10 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
} else {
// The peak and hold falls back to peak
// after 20 seconds.
qreal timeSinceLastPeak = (uint64_t)(ts -
displayPeakHoldLastUpdateTime[channelNr]) * 0.000000001;
qreal timeSinceLastPeak =
(uint64_t)(ts -
displayPeakHoldLastUpdateTime[channelNr]) *
0.000000001;
if (timeSinceLastPeak > peakHoldDuration) {
displayPeakHold[channelNr] = currentPeak[channelNr];
displayPeakHoldLastUpdateTime[channelNr] = ts;
@ -666,21 +667,22 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
}
if (currentInputPeak[channelNr] >= displayInputPeakHold[channelNr] ||
!isfinite(displayInputPeakHold[channelNr])) {
!isfinite(displayInputPeakHold[channelNr])) {
// Attack of peak-hold is immediate, but keep track
// when it was last updated.
displayInputPeakHold[channelNr] = currentInputPeak[channelNr];
displayInputPeakHoldLastUpdateTime[channelNr] = ts;
} else {
// The peak and hold falls back to peak after 1 second.
qreal timeSinceLastPeak = (uint64_t)(ts -
displayInputPeakHoldLastUpdateTime[channelNr]) *
qreal timeSinceLastPeak =
(uint64_t)(
ts -
displayInputPeakHoldLastUpdateTime[channelNr]) *
0.000000001;
if (timeSinceLastPeak > inputPeakHoldDuration) {
displayInputPeakHold[channelNr] =
currentInputPeak[channelNr];
displayInputPeakHoldLastUpdateTime[channelNr] =
ts;
displayInputPeakHoldLastUpdateTime[channelNr] = ts;
}
}
@ -692,27 +694,29 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
// A VU meter will integrate to the new value to 99% in 300 ms.
// The calculation here is very simplified and is more accurate
// with higher frame-rate.
float attack = float((currentMagnitude[channelNr] -
displayMagnitude[channelNr]) *
(timeSinceLastRedraw /
magnitudeIntegrationTime) * 0.99);
displayMagnitude[channelNr] = CLAMP(displayMagnitude[channelNr]
+ attack, (float)minimumLevel, 0);
float attack =
float((currentMagnitude[channelNr] -
displayMagnitude[channelNr]) *
(timeSinceLastRedraw / magnitudeIntegrationTime) *
0.99);
displayMagnitude[channelNr] =
CLAMP(displayMagnitude[channelNr] + attack,
(float)minimumLevel, 0);
}
}
inline void VolumeMeter::calculateBallistics(uint64_t ts,
qreal timeSinceLastRedraw)
qreal timeSinceLastRedraw)
{
QMutexLocker locker(&dataMutex);
for (int channelNr = 0; channelNr < MAX_AUDIO_CHANNELS; channelNr++)
calculateBallisticsForChannel(channelNr, ts,
timeSinceLastRedraw);
timeSinceLastRedraw);
}
void VolumeMeter::paintInputMeter(QPainter &painter, int x, int y, int width,
int height, float peakHold)
int height, float peakHold)
{
QMutexLocker locker(&dataMutex);
QColor color;
@ -732,7 +736,7 @@ void VolumeMeter::paintInputMeter(QPainter &painter, int x, int y, int width,
}
void VolumeMeter::paintHTicks(QPainter &painter, int x, int y, int width,
int height)
int height)
{
qreal scale = width / minimumLevel;
@ -740,7 +744,7 @@ void VolumeMeter::paintHTicks(QPainter &painter, int x, int y, int width,
painter.setPen(majorTickColor);
// Draw major tick lines and numeric indicators.
for (int i = 0; i >= minimumLevel; i-= 5) {
for (int i = 0; i >= minimumLevel; i -= 5) {
int position = int(x + width - (i * scale) - 1);
QString str = QString::number(i);
@ -768,7 +772,7 @@ void VolumeMeter::paintVTicks(QPainter &painter, int x, int y, int height)
painter.setPen(majorTickColor);
// Draw major tick lines and numeric indicators.
for (int i = 0; i >= minimumLevel; i-= 5) {
for (int i = 0; i >= minimumLevel; i -= 5) {
int position = y + int((i * scale) - 1);
QString str = QString::number(i);
@ -798,22 +802,23 @@ void VolumeMeter::ClipEnding()
}
void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
int height, float magnitude, float peak, float peakHold)
int height, float magnitude, float peak,
float peakHold)
{
qreal scale = width / minimumLevel;
QMutexLocker locker(&dataMutex);
int minimumPosition = x + 0;
int maximumPosition = x + width;
int magnitudePosition = int(x + width - (magnitude * scale));
int peakPosition = int(x + width - (peak * scale));
int peakHoldPosition = int(x + width - (peakHold * scale));
int warningPosition = int(x + width - (warningLevel * scale));
int errorPosition = int(x + width - (errorLevel * scale));
int minimumPosition = x + 0;
int maximumPosition = x + width;
int magnitudePosition = int(x + width - (magnitude * scale));
int peakPosition = int(x + width - (peak * scale));
int peakHoldPosition = int(x + width - (peakHold * scale));
int warningPosition = int(x + width - (warningLevel * scale));
int errorPosition = int(x + width - (errorLevel * scale));
int nominalLength = warningPosition - minimumPosition;
int warningLength = errorPosition - warningPosition;
int errorLength = maximumPosition - errorPosition;
int nominalLength = warningPosition - minimumPosition;
int warningLength = errorPosition - warningPosition;
int errorLength = maximumPosition - errorPosition;
locker.unlock();
if (clipping) {
@ -822,87 +827,89 @@ void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
if (peakPosition < minimumPosition) {
painter.fillRect(minimumPosition, y, nominalLength, height,
backgroundNominalColor);
backgroundNominalColor);
painter.fillRect(warningPosition, y, warningLength, height,
backgroundWarningColor);
backgroundWarningColor);
painter.fillRect(errorPosition, y, errorLength, height,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < warningPosition) {
painter.fillRect(minimumPosition, y, peakPosition -
minimumPosition, height,
foregroundNominalColor);
painter.fillRect(peakPosition, y, warningPosition -
peakPosition, height, backgroundNominalColor);
painter.fillRect(minimumPosition, y,
peakPosition - minimumPosition, height,
foregroundNominalColor);
painter.fillRect(peakPosition, y,
warningPosition - peakPosition, height,
backgroundNominalColor);
painter.fillRect(warningPosition, y, warningLength, height,
backgroundWarningColor);
backgroundWarningColor);
painter.fillRect(errorPosition, y, errorLength, height,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < errorPosition) {
painter.fillRect(minimumPosition, y, nominalLength, height,
foregroundNominalColor);
foregroundNominalColor);
painter.fillRect(warningPosition, y,
peakPosition - warningPosition, height,
foregroundWarningColor);
painter.fillRect(peakPosition, y, errorPosition -
peakPosition, height, backgroundWarningColor);
peakPosition - warningPosition, height,
foregroundWarningColor);
painter.fillRect(peakPosition, y, errorPosition - peakPosition,
height, backgroundWarningColor);
painter.fillRect(errorPosition, y, errorLength, height,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < maximumPosition) {
painter.fillRect(minimumPosition, y, nominalLength, height,
foregroundNominalColor);
foregroundNominalColor);
painter.fillRect(warningPosition, y, warningLength, height,
foregroundWarningColor);
foregroundWarningColor);
painter.fillRect(errorPosition, y, peakPosition - errorPosition,
height, foregroundErrorColor);
height, foregroundErrorColor);
painter.fillRect(peakPosition, y,
maximumPosition - peakPosition, height,
backgroundErrorColor);
maximumPosition - peakPosition, height,
backgroundErrorColor);
} else {
if (!clipping) {
QTimer::singleShot(CLIP_FLASH_DURATION_MS, this,
SLOT(ClipEnding()));
SLOT(ClipEnding()));
clipping = true;
}
int end = errorLength + warningLength + nominalLength;
painter.fillRect(minimumPosition, y, end, height,
QBrush(foregroundErrorColor));
QBrush(foregroundErrorColor));
}
if (peakHoldPosition - 3 < minimumPosition)
;// Peak-hold below minimum, no drawing.
; // Peak-hold below minimum, no drawing.
else if (peakHoldPosition < warningPosition)
painter.fillRect(peakHoldPosition - 3, y, 3, height,
foregroundNominalColor);
foregroundNominalColor);
else if (peakHoldPosition < errorPosition)
painter.fillRect(peakHoldPosition - 3, y, 3, height,
foregroundWarningColor);
foregroundWarningColor);
else
painter.fillRect(peakHoldPosition - 3, y, 3, height,
foregroundErrorColor);
foregroundErrorColor);
if (magnitudePosition - 3 >= minimumPosition)
painter.fillRect(magnitudePosition - 3, y, 3, height,
magnitudeColor);
magnitudeColor);
}
void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,
int height, float magnitude, float peak, float peakHold)
int height, float magnitude, float peak,
float peakHold)
{
qreal scale = height / minimumLevel;
QMutexLocker locker(&dataMutex);
int minimumPosition = y + 0;
int maximumPosition = y + height;
int magnitudePosition = int(y + height - (magnitude * scale));
int peakPosition = int(y + height - (peak * scale));
int peakHoldPosition = int(y + height - (peakHold * scale));
int warningPosition = int(y + height - (warningLevel * scale));
int errorPosition = int(y + height - (errorLevel * scale));
int minimumPosition = y + 0;
int maximumPosition = y + height;
int magnitudePosition = int(y + height - (magnitude * scale));
int peakPosition = int(y + height - (peak * scale));
int peakHoldPosition = int(y + height - (peakHold * scale));
int warningPosition = int(y + height - (warningLevel * scale));
int errorPosition = int(y + height - (errorLevel * scale));
int nominalLength = warningPosition - minimumPosition;
int warningLength = errorPosition - warningPosition;
int errorLength = maximumPosition - errorPosition;
int nominalLength = warningPosition - minimumPosition;
int warningLength = errorPosition - warningPosition;
int errorLength = maximumPosition - errorPosition;
locker.unlock();
if (clipping) {
@ -911,65 +918,71 @@ void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,
if (peakPosition < minimumPosition) {
painter.fillRect(x, minimumPosition, width, nominalLength,
backgroundNominalColor);
backgroundNominalColor);
painter.fillRect(x, warningPosition, width, warningLength,
backgroundWarningColor);
backgroundWarningColor);
painter.fillRect(x, errorPosition, width, errorLength,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < warningPosition) {
painter.fillRect(x, minimumPosition, width, peakPosition -
minimumPosition, foregroundNominalColor);
painter.fillRect(x, peakPosition, width, warningPosition -
peakPosition, backgroundNominalColor);
painter.fillRect(x, minimumPosition, width,
peakPosition - minimumPosition,
foregroundNominalColor);
painter.fillRect(x, peakPosition, width,
warningPosition - peakPosition,
backgroundNominalColor);
painter.fillRect(x, warningPosition, width, warningLength,
backgroundWarningColor);
backgroundWarningColor);
painter.fillRect(x, errorPosition, width, errorLength,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < errorPosition) {
painter.fillRect(x,minimumPosition, width, nominalLength,
foregroundNominalColor);
painter.fillRect(x, warningPosition, width, peakPosition -
warningPosition, foregroundWarningColor);
painter.fillRect(x, peakPosition, width, errorPosition -
peakPosition, backgroundWarningColor);
painter.fillRect(x, minimumPosition, width, nominalLength,
foregroundNominalColor);
painter.fillRect(x, warningPosition, width,
peakPosition - warningPosition,
foregroundWarningColor);
painter.fillRect(x, peakPosition, width,
errorPosition - peakPosition,
backgroundWarningColor);
painter.fillRect(x, errorPosition, width, errorLength,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < maximumPosition) {
painter.fillRect(x, minimumPosition, width, nominalLength,
foregroundNominalColor);
foregroundNominalColor);
painter.fillRect(x, warningPosition, width, warningLength,
foregroundWarningColor);
painter.fillRect(x, errorPosition, width, peakPosition -
errorPosition, foregroundErrorColor);
painter.fillRect(x, peakPosition, width, maximumPosition -
peakPosition, backgroundErrorColor);
foregroundWarningColor);
painter.fillRect(x, errorPosition, width,
peakPosition - errorPosition,
foregroundErrorColor);
painter.fillRect(x, peakPosition, width,
maximumPosition - peakPosition,
backgroundErrorColor);
} else {
if (!clipping) {
QTimer::singleShot(CLIP_FLASH_DURATION_MS, this,
SLOT(ClipEnding()));
SLOT(ClipEnding()));
clipping = true;
}
int end = errorLength + warningLength + nominalLength;
painter.fillRect(x, minimumPosition, width, end,
QBrush(foregroundErrorColor));
QBrush(foregroundErrorColor));
}
if (peakHoldPosition - 3 < minimumPosition)
;// Peak-hold below minimum, no drawing.
; // Peak-hold below minimum, no drawing.
else if (peakHoldPosition < warningPosition)
painter.fillRect(x, peakHoldPosition - 3, width, 3,
foregroundNominalColor);
foregroundNominalColor);
else if (peakHoldPosition < errorPosition)
painter.fillRect(x, peakHoldPosition - 3, width, 3,
foregroundWarningColor);
foregroundWarningColor);
else
painter.fillRect(x, peakHoldPosition - 3, width, 3,
foregroundErrorColor);
foregroundErrorColor);
if (magnitudePosition - 3 >= minimumPosition)
painter.fillRect(x, magnitudePosition - 3, width, 3,
magnitudeColor);
magnitudeColor);
}
void VolumeMeter::paintEvent(QPaintEvent *event)
@ -978,7 +991,7 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
qreal timeSinceLastRedraw = (ts - lastRedrawTime) * 0.000000001;
const QRect rect = event->region().boundingRect();
int width = rect.width();
int width = rect.width();
int height = rect.height();
handleChannelCofigurationChange();
@ -992,7 +1005,7 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
else
tickPaintCacheSize = QSize(width, 9);
if (tickPaintCache == nullptr ||
tickPaintCache->size() != tickPaintCacheSize) {
tickPaintCache->size() != tickPaintCacheSize) {
delete tickPaintCache;
tickPaintCache = new QPixmap(tickPaintCacheSize);
@ -1004,11 +1017,11 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
tickPainter.translate(0, height);
tickPainter.scale(1, -1);
paintVTicks(tickPainter, 0, 11,
tickPaintCacheSize.height() - 11);
tickPaintCacheSize.height() - 11);
} else {
paintHTicks(tickPainter, 6, 0,
tickPaintCacheSize.width() - 6,
tickPaintCacheSize.height());
tickPaintCacheSize.width() - 6,
tickPaintCacheSize.height());
}
tickPainter.end();
}
@ -1020,29 +1033,29 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
painter.translate(0, height);
painter.scale(1, -1);
painter.drawPixmap(displayNrAudioChannels * 4 - 1, 7,
*tickPaintCache);
*tickPaintCache);
} else {
painter.drawPixmap(0, height - 9, *tickPaintCache);
}
for (int channelNr = 0; channelNr < displayNrAudioChannels;
channelNr++) {
channelNr++) {
int channelNrFixed = (displayNrAudioChannels == 1 &&
channels > 2)
? 2
: channelNr;
int channelNrFixed =
(displayNrAudioChannels == 1 && channels > 2)
? 2
: channelNr;
if (vertical)
paintVMeter(painter, channelNr * 4, 8, 3, height - 10,
displayMagnitude[channelNrFixed],
displayPeak[channelNrFixed],
displayPeakHold[channelNrFixed]);
displayMagnitude[channelNrFixed],
displayPeak[channelNrFixed],
displayPeakHold[channelNrFixed]);
else
paintHMeter(painter, 5, channelNr * 4, width - 5, 3,
displayMagnitude[channelNrFixed],
displayPeak[channelNrFixed],
displayPeakHold[channelNrFixed]);
displayMagnitude[channelNrFixed],
displayPeak[channelNrFixed],
displayPeakHold[channelNrFixed]);
if (idle)
continue;
@ -1071,7 +1084,7 @@ void VolumeMeterTimer::RemoveVolControl(VolumeMeter *meter)
volumeMeters.removeOne(meter);
}
void VolumeMeterTimer::timerEvent(QTimerEvent*)
void VolumeMeterTimer::timerEvent(QTimerEvent *)
{
for (VolumeMeter *meter : volumeMeters)
meter->update();

View File

@ -11,74 +11,55 @@
class QPushButton;
class VolumeMeterTimer;
class VolumeMeter : public QWidget
{
class VolumeMeter : public QWidget {
Q_OBJECT
Q_PROPERTY(QColor backgroundNominalColor
READ getBackgroundNominalColor
WRITE setBackgroundNominalColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundWarningColor
READ getBackgroundWarningColor
WRITE setBackgroundWarningColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundErrorColor
READ getBackgroundErrorColor
WRITE setBackgroundErrorColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundNominalColor
READ getForegroundNominalColor
WRITE setForegroundNominalColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundWarningColor
READ getForegroundWarningColor
WRITE setForegroundWarningColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundErrorColor
READ getForegroundErrorColor
WRITE setForegroundErrorColor DESIGNABLE true)
Q_PROPERTY(QColor clipColor
READ getClipColor
WRITE setClipColor DESIGNABLE true)
Q_PROPERTY(QColor magnitudeColor
READ getMagnitudeColor
WRITE setMagnitudeColor DESIGNABLE true)
Q_PROPERTY(QColor majorTickColor
READ getMajorTickColor
WRITE setMajorTickColor DESIGNABLE true)
Q_PROPERTY(QColor minorTickColor
READ getMinorTickColor
WRITE setMinorTickColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundNominalColor READ getBackgroundNominalColor
WRITE setBackgroundNominalColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundWarningColor READ getBackgroundWarningColor
WRITE setBackgroundWarningColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundErrorColor READ getBackgroundErrorColor
WRITE setBackgroundErrorColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundNominalColor READ getForegroundNominalColor
WRITE setForegroundNominalColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundWarningColor READ getForegroundWarningColor
WRITE setForegroundWarningColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundErrorColor READ getForegroundErrorColor
WRITE setForegroundErrorColor DESIGNABLE true)
Q_PROPERTY(QColor clipColor READ getClipColor WRITE setClipColor
DESIGNABLE true)
Q_PROPERTY(QColor magnitudeColor READ getMagnitudeColor WRITE
setMagnitudeColor DESIGNABLE true)
Q_PROPERTY(QColor majorTickColor READ getMajorTickColor WRITE
setMajorTickColor DESIGNABLE true)
Q_PROPERTY(QColor minorTickColor READ getMinorTickColor WRITE
setMinorTickColor DESIGNABLE true)
// Levels are denoted in dBFS.
Q_PROPERTY(qreal minimumLevel
READ getMinimumLevel
WRITE setMinimumLevel DESIGNABLE true)
Q_PROPERTY(qreal warningLevel
READ getWarningLevel
WRITE setWarningLevel DESIGNABLE true)
Q_PROPERTY(qreal errorLevel
READ getErrorLevel
WRITE setErrorLevel DESIGNABLE true)
Q_PROPERTY(qreal clipLevel
READ getClipLevel
WRITE setClipLevel DESIGNABLE true)
Q_PROPERTY(qreal minimumInputLevel
READ getMinimumInputLevel
WRITE setMinimumInputLevel DESIGNABLE true)
Q_PROPERTY(qreal minimumLevel READ getMinimumLevel WRITE setMinimumLevel
DESIGNABLE true)
Q_PROPERTY(qreal warningLevel READ getWarningLevel WRITE setWarningLevel
DESIGNABLE true)
Q_PROPERTY(qreal errorLevel READ getErrorLevel WRITE setErrorLevel
DESIGNABLE true)
Q_PROPERTY(qreal clipLevel READ getClipLevel WRITE setClipLevel
DESIGNABLE true)
Q_PROPERTY(qreal minimumInputLevel READ getMinimumInputLevel WRITE
setMinimumInputLevel DESIGNABLE true)
// Rates are denoted in dB/second.
Q_PROPERTY(qreal peakDecayRate
READ getPeakDecayRate
WRITE setPeakDecayRate DESIGNABLE true)
Q_PROPERTY(qreal peakDecayRate READ getPeakDecayRate WRITE
setPeakDecayRate DESIGNABLE true)
// Time in seconds for the VU meter to integrate over.
Q_PROPERTY(qreal magnitudeIntegrationTime
READ getMagnitudeIntegrationTime
WRITE setMagnitudeIntegrationTime DESIGNABLE true)
Q_PROPERTY(
qreal magnitudeIntegrationTime READ getMagnitudeIntegrationTime
WRITE setMagnitudeIntegrationTime DESIGNABLE true)
// Duration is denoted in seconds.
Q_PROPERTY(qreal peakHoldDuration
READ getPeakHoldDuration
WRITE setPeakHoldDuration DESIGNABLE true)
Q_PROPERTY(qreal inputPeakHoldDuration
READ getInputPeakHoldDuration
WRITE setInputPeakHoldDuration DESIGNABLE true)
Q_PROPERTY(qreal peakHoldDuration READ getPeakHoldDuration WRITE
setPeakHoldDuration DESIGNABLE true)
Q_PROPERTY(qreal inputPeakHoldDuration READ getInputPeakHoldDuration
WRITE setInputPeakHoldDuration DESIGNABLE true)
private slots:
void ClipEnding();
@ -92,18 +73,18 @@ private:
inline void handleChannelCofigurationChange();
inline bool detectIdle(uint64_t ts);
inline void calculateBallistics(uint64_t ts,
qreal timeSinceLastRedraw=0.0);
inline void calculateBallisticsForChannel(int channelNr,
uint64_t ts, qreal timeSinceLastRedraw);
qreal timeSinceLastRedraw = 0.0);
inline void calculateBallisticsForChannel(int channelNr, uint64_t ts,
qreal timeSinceLastRedraw);
void paintInputMeter(QPainter &painter, int x, int y, int width,
int height, float peakHold);
int height, float peakHold);
void paintHMeter(QPainter &painter, int x, int y, int width, int height,
float magnitude, float peak, float peakHold);
float magnitude, float peak, float peakHold);
void paintHTicks(QPainter &painter, int x, int y, int width,
int height);
int height);
void paintVMeter(QPainter &painter, int x, int y, int width, int height,
float magnitude, float peak, float peakHold);
float magnitude, float peak, float peakHold);
void paintVTicks(QPainter &painter, int x, int y, int height);
QMutex dataMutex;
@ -150,14 +131,13 @@ private:
public:
explicit VolumeMeter(QWidget *parent = nullptr,
obs_volmeter_t *obs_volmeter = nullptr,
bool vertical = false);
obs_volmeter_t *obs_volmeter = nullptr,
bool vertical = false);
~VolumeMeter();
void setLevels(
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS]);
void setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS]);
QColor getBackgroundNominalColor() const;
void setBackgroundNominalColor(QColor c);
@ -216,7 +196,7 @@ public:
protected:
void timerEvent(QTimerEvent *event) override;
QList<VolumeMeter*> volumeMeters;
QList<VolumeMeter *> volumeMeters;
};
class QLabel;
@ -228,23 +208,23 @@ class VolControl : public QWidget {
private:
OBSSource source;
QLabel *nameLabel;
QLabel *volLabel;
VolumeMeter *volMeter;
QSlider *slider;
MuteCheckBox *mute;
QPushButton *config = nullptr;
float levelTotal;
float levelCount;
obs_fader_t *obs_fader;
obs_volmeter_t *obs_volmeter;
bool vertical;
QLabel *nameLabel;
QLabel *volLabel;
VolumeMeter *volMeter;
QSlider *slider;
MuteCheckBox *mute;
QPushButton *config = nullptr;
float levelTotal;
float levelCount;
obs_fader_t *obs_fader;
obs_volmeter_t *obs_volmeter;
bool vertical;
static void OBSVolumeChanged(void *param, float db);
static void OBSVolumeLevel(void *data,
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS]);
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS]);
static void OBSVolumeMuted(void *data, calldata_t *calldata);
void EmitConfigClicked();
@ -262,10 +242,10 @@ signals:
public:
explicit VolControl(OBSSource source, bool showConfig = false,
bool vertical = false);
bool vertical = false);
~VolControl();
inline obs_source_t *GetSource() const {return source;}
inline obs_source_t *GetSource() const { return source; }
QString GetName() const;
void SetName(const QString &newName);

View File

@ -2,10 +2,9 @@
#include "obs-app.hpp"
OBSUpdate::OBSUpdate(QWidget *parent, bool manualUpdate, const QString &text)
: QDialog (parent, Qt::WindowSystemMenuHint |
Qt::WindowTitleHint |
Qt::WindowCloseButtonHint),
ui (new Ui_OBSUpdate)
: QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint |
Qt::WindowCloseButtonHint),
ui(new Ui_OBSUpdate)
{
ui->setupUi(this);
ui->text->setHtml(text);

View File

@ -9,11 +9,7 @@ class OBSUpdate : public QDialog {
Q_OBJECT
public:
enum ReturnVal {
No,
Yes,
Skip
};
enum ReturnVal { No, Yes, Skip };
OBSUpdate(QWidget *parent, bool manualUpdate, const QString &text);

View File

@ -26,7 +26,7 @@ void HashToString(const uint8_t *in, wchar_t *out)
const wchar_t alphabet[] = L"0123456789abcdef";
for (int i = 0; i != BLAKE2_HASH_LENGTH; ++i) {
out[2 * i] = alphabet[in[i] / 16];
out[2 * i] = alphabet[in[i] / 16];
out[2 * i + 1] = alphabet[in[i] % 16];
}
@ -50,7 +50,7 @@ bool CalculateFileHash(const wchar_t *path, BYTE *hash)
return false;
WinHandle handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, 0, nullptr);
nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
return false;
@ -60,7 +60,7 @@ bool CalculateFileHash(const wchar_t *path, BYTE *hash)
for (;;) {
DWORD read = 0;
if (!ReadFile(handle, buf.data(), (DWORD)buf.size(), &read,
nullptr))
nullptr))
return false;
if (!read)

View File

@ -20,7 +20,7 @@
using namespace std;
#define MAX_BUF_SIZE 262144
#define MAX_BUF_SIZE 262144
#define READ_BUF_SIZE 32768
/* ------------------------------------------------------------------------ */
@ -36,8 +36,8 @@ public:
inflateEnd(&strm);
}
inline operator z_stream*() {return &strm;}
inline z_stream *operator->() {return &strm;}
inline operator z_stream *() { return &strm; }
inline z_stream *operator->() { return &strm; }
inline bool inflate()
{
@ -50,14 +50,15 @@ public:
/* ------------------------------------------------------------------------ */
static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm,
string &zipBuf, const uint8_t *buffer, DWORD outSize)
string &zipBuf, const uint8_t *buffer,
DWORD outSize)
{
strm->avail_in = outSize;
strm->next_in = buffer;
strm->next_in = buffer;
do {
strm->avail_out = (uInt)zipBuf.size();
strm->next_out = (Bytef *)zipBuf.data();
strm->next_out = (Bytef *)zipBuf.data();
int zret = inflate(strm, Z_NO_FLUSH);
if (zret != Z_STREAM_END && zret != Z_OK)
@ -65,7 +66,7 @@ static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm,
try {
responseBuf.append(zipBuf.data(),
zipBuf.size() - strm->avail_out);
zipBuf.size() - strm->avail_out);
} catch (...) {
return false;
}
@ -75,7 +76,7 @@ static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm,
}
static bool ReadHTTPData(string &responseBuf, const uint8_t *buffer,
DWORD outSize)
DWORD outSize)
{
try {
responseBuf.append((const char *)buffer, outSize);
@ -85,19 +86,16 @@ static bool ReadHTTPData(string &responseBuf, const uint8_t *buffer,
return true;
}
bool HTTPPostData(const wchar_t *url,
const BYTE * data,
int dataLen,
const wchar_t *extraHeaders,
int * responseCode,
string & responseBuf)
bool HTTPPostData(const wchar_t *url, const BYTE *data, int dataLen,
const wchar_t *extraHeaders, int *responseCode,
string &responseBuf)
{
HttpHandle hSession;
HttpHandle hConnect;
HttpHandle hRequest;
string zipBuf;
HttpHandle hSession;
HttpHandle hConnect;
HttpHandle hRequest;
string zipBuf;
URL_COMPONENTS urlComponents = {};
bool secure = false;
bool secure = false;
wchar_t hostName[256];
wchar_t path[1024];
@ -113,10 +111,10 @@ bool HTTPPostData(const wchar_t *url,
urlComponents.dwStructSize = sizeof(urlComponents);
urlComponents.lpszHostName = hostName;
urlComponents.lpszHostName = hostName;
urlComponents.dwHostNameLength = _countof(hostName);
urlComponents.lpszUrlPath = path;
urlComponents.lpszUrlPath = path;
urlComponents.dwUrlPathLength = _countof(path);
WinHttpCrackUrl(url, 0, 0, &urlComponents);
@ -128,22 +126,21 @@ bool HTTPPostData(const wchar_t *url,
* connect to server */
hSession = WinHttpOpen(L"OBS Studio Updater/2.1",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS,
0);
if (!hSession) {
*responseCode = -1;
return false;
}
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS,
(LPVOID)&tlsProtocols, sizeof(tlsProtocols));
(LPVOID)&tlsProtocols, sizeof(tlsProtocols));
hConnect = WinHttpConnect(hSession, hostName,
secure
? INTERNET_DEFAULT_HTTPS_PORT
: INTERNET_DEFAULT_HTTP_PORT, 0);
secure ? INTERNET_DEFAULT_HTTPS_PORT
: INTERNET_DEFAULT_HTTP_PORT,
0);
if (!hConnect) {
*responseCode = -2;
return false;
@ -152,24 +149,19 @@ bool HTTPPostData(const wchar_t *url,
/* -------------------------------------- *
* request data */
hRequest = WinHttpOpenRequest(hConnect,
L"POST",
path,
nullptr,
WINHTTP_NO_REFERER,
acceptTypes,
secure
? WINHTTP_FLAG_SECURE |
WINHTTP_FLAG_REFRESH
: WINHTTP_FLAG_REFRESH);
hRequest = WinHttpOpenRequest(hConnect, L"POST", path, nullptr,
WINHTTP_NO_REFERER, acceptTypes,
secure ? WINHTTP_FLAG_SECURE |
WINHTTP_FLAG_REFRESH
: WINHTTP_FLAG_REFRESH);
if (!hRequest) {
*responseCode = -3;
return false;
}
bool bResults = !!WinHttpSendRequest(hRequest, extraHeaders,
extraHeaders ? -1 : 0,
(void *)data, dataLen, dataLen, 0);
extraHeaders ? -1 : 0,
(void *)data, dataLen, dataLen, 0);
/* -------------------------------------- *
* end request */
@ -185,18 +177,15 @@ bool HTTPPostData(const wchar_t *url,
* get headers */
wchar_t encoding[64];
DWORD encodingLen;
DWORD encodingLen;
wchar_t statusCode[8];
DWORD statusCodeLen;
DWORD statusCodeLen;
statusCodeLen = sizeof(statusCode);
if (!WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_STATUS_CODE,
WINHTTP_HEADER_NAME_BY_INDEX,
&statusCode,
&statusCodeLen,
WINHTTP_NO_HEADER_INDEX)) {
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE,
WINHTTP_HEADER_NAME_BY_INDEX, &statusCode,
&statusCodeLen, WINHTTP_NO_HEADER_INDEX)) {
*responseCode = -4;
return false;
} else {
@ -204,12 +193,9 @@ bool HTTPPostData(const wchar_t *url,
}
encodingLen = sizeof(encoding);
if (!WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_CONTENT_ENCODING,
WINHTTP_HEADER_NAME_BY_INDEX,
encoding,
&encodingLen,
WINHTTP_NO_HEADER_INDEX)) {
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_ENCODING,
WINHTTP_HEADER_NAME_BY_INDEX, encoding,
&encodingLen, WINHTTP_NO_HEADER_INDEX)) {
encoding[0] = 0;
if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND) {
*responseCode = -5;
@ -238,11 +224,11 @@ bool HTTPPostData(const wchar_t *url,
bool gzip = wcscmp(encoding, L"gzip") == 0;
if (gzip) {
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
strm->avail_in = 0;
strm->next_in = Z_NULL;
strm->next_in = Z_NULL;
if (!strm.inflate())
return false;
@ -278,7 +264,7 @@ bool HTTPPostData(const wchar_t *url,
dwSize = std::min(dwSize, (DWORD)sizeof(buffer));
if (!WinHttpReadData(hRequest, (void *)buffer, dwSize,
&outSize)) {
&outSize)) {
*responseCode = -9;
return false;
}
@ -311,25 +297,23 @@ bool HTTPPostData(const wchar_t *url,
/* ------------------------------------------------------------------------ */
static bool ReadHTTPZippedFile(z_stream *strm, HANDLE updateFile,
string &zipBuf, const uint8_t *buffer, DWORD outSize,
int *responseCode)
string &zipBuf, const uint8_t *buffer,
DWORD outSize, int *responseCode)
{
strm->avail_in = outSize;
strm->next_in = buffer;
strm->next_in = buffer;
do {
strm->avail_out = (uInt)zipBuf.size();
strm->next_out = (Bytef *)zipBuf.data();
strm->next_out = (Bytef *)zipBuf.data();
int zret = inflate(strm, Z_NO_FLUSH);
if (zret != Z_STREAM_END && zret != Z_OK)
return false;
DWORD written;
if (!WriteFile(updateFile,
zipBuf.data(),
MAX_BUF_SIZE - strm->avail_out,
&written,
if (!WriteFile(updateFile, zipBuf.data(),
MAX_BUF_SIZE - strm->avail_out, &written,
nullptr)) {
*responseCode = -10;
return false;
@ -346,7 +330,7 @@ static bool ReadHTTPZippedFile(z_stream *strm, HANDLE updateFile,
}
static bool ReadHTTPFile(HANDLE updateFile, const uint8_t *buffer,
DWORD outSize, int *responseCode)
DWORD outSize, int *responseCode)
{
DWORD written;
if (!WriteFile(updateFile, buffer, outSize, &written, nullptr)) {
@ -363,20 +347,18 @@ static bool ReadHTTPFile(HANDLE updateFile, const uint8_t *buffer,
return true;
}
bool HTTPGetFile(HINTERNET hConnect,
const wchar_t *url,
const wchar_t *outputPath,
const wchar_t *extraHeaders,
int * responseCode)
bool HTTPGetFile(HINTERNET hConnect, const wchar_t *url,
const wchar_t *outputPath, const wchar_t *extraHeaders,
int *responseCode)
{
HttpHandle hRequest;
const wchar_t *acceptTypes[] = {L"*/*", nullptr};
URL_COMPONENTS urlComponents = {};
bool secure = false;
bool secure = false;
string zipBuf;
string zipBuf;
wchar_t hostName[256];
wchar_t path[1024];
@ -385,10 +367,10 @@ bool HTTPGetFile(HINTERNET hConnect,
urlComponents.dwStructSize = sizeof(urlComponents);
urlComponents.lpszHostName = hostName;
urlComponents.lpszHostName = hostName;
urlComponents.dwHostNameLength = _countof(hostName);
urlComponents.lpszUrlPath = path;
urlComponents.lpszUrlPath = path;
urlComponents.dwUrlPathLength = _countof(path);
WinHttpCrackUrl(url, 0, 0, &urlComponents);
@ -399,23 +381,19 @@ bool HTTPGetFile(HINTERNET hConnect,
/* -------------------------------------- *
* request data */
hRequest = WinHttpOpenRequest(hConnect,
L"GET",
path,
nullptr,
WINHTTP_NO_REFERER,
acceptTypes,
secure
? WINHTTP_FLAG_SECURE |
WINHTTP_FLAG_REFRESH
: WINHTTP_FLAG_REFRESH);
hRequest = WinHttpOpenRequest(hConnect, L"GET", path, nullptr,
WINHTTP_NO_REFERER, acceptTypes,
secure ? WINHTTP_FLAG_SECURE |
WINHTTP_FLAG_REFRESH
: WINHTTP_FLAG_REFRESH);
if (!hRequest) {
*responseCode = -3;
return false;
}
bool bResults = !!WinHttpSendRequest(hRequest, extraHeaders,
extraHeaders ? -1 : 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
extraHeaders ? -1 : 0,
WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
/* -------------------------------------- *
* end request */
@ -431,18 +409,15 @@ bool HTTPGetFile(HINTERNET hConnect,
* get headers */
wchar_t encoding[64];
DWORD encodingLen;
DWORD encodingLen;
wchar_t statusCode[8];
DWORD statusCodeLen;
DWORD statusCodeLen;
statusCodeLen = sizeof(statusCode);
if (!WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_STATUS_CODE,
WINHTTP_HEADER_NAME_BY_INDEX,
&statusCode,
&statusCodeLen,
WINHTTP_NO_HEADER_INDEX)) {
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE,
WINHTTP_HEADER_NAME_BY_INDEX, &statusCode,
&statusCodeLen, WINHTTP_NO_HEADER_INDEX)) {
*responseCode = -4;
return false;
} else {
@ -450,12 +425,9 @@ bool HTTPGetFile(HINTERNET hConnect,
}
encodingLen = sizeof(encoding);
if (!WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_CONTENT_ENCODING,
WINHTTP_HEADER_NAME_BY_INDEX,
encoding,
&encodingLen,
WINHTTP_NO_HEADER_INDEX)) {
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_ENCODING,
WINHTTP_HEADER_NAME_BY_INDEX, encoding,
&encodingLen, WINHTTP_NO_HEADER_INDEX)) {
encoding[0] = 0;
if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND) {
*responseCode = -5;
@ -472,11 +444,11 @@ bool HTTPGetFile(HINTERNET hConnect,
bool gzip = wcscmp(encoding, L"gzip") == 0;
if (gzip) {
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
strm->avail_in = 0;
strm->next_in = Z_NULL;
strm->next_in = Z_NULL;
if (!strm.inflate())
return false;
@ -498,12 +470,12 @@ bool HTTPGetFile(HINTERNET hConnect,
if (!bResults || *responseCode != 200)
return true;
BYTE buffer[READ_BUF_SIZE];
BYTE buffer[READ_BUF_SIZE];
DWORD dwSize, outSize;
int lastPosition = 0;
int lastPosition = 0;
WinHandle updateFile = CreateFile(outputPath, GENERIC_WRITE, 0,
nullptr, CREATE_ALWAYS, 0, nullptr);
WinHandle updateFile = CreateFile(outputPath, GENERIC_WRITE, 0, nullptr,
CREATE_ALWAYS, 0, nullptr);
if (!updateFile.Valid()) {
*responseCode = -7;
return false;
@ -520,7 +492,7 @@ bool HTTPGetFile(HINTERNET hConnect,
dwSize = std::min(dwSize, (DWORD)sizeof(buffer));
if (!WinHttpReadData(hRequest, (void *)buffer, dwSize,
&outSize)) {
&outSize)) {
*responseCode = -9;
return false;
} else {
@ -529,21 +501,22 @@ bool HTTPGetFile(HINTERNET hConnect,
if (gzip) {
if (!ReadHTTPZippedFile(strm, updateFile,
zipBuf, buffer,
outSize, responseCode))
zipBuf, buffer, outSize,
responseCode))
return false;
} else {
if (!ReadHTTPFile(updateFile, buffer,
outSize, responseCode))
if (!ReadHTTPFile(updateFile, buffer, outSize,
responseCode))
return false;
}
int position = (int)(((float)completedFileSize /
(float)totalFileSize) * 100.0f);
(float)totalFileSize) *
100.0f);
if (position > lastPosition) {
lastPosition = position;
SendDlgItemMessage(hwndMain, IDC_PROGRESS,
PBM_SETPOS, position, 0);
PBM_SETPOS, position, 0);
}
}

View File

@ -20,16 +20,16 @@
#include <vector>
#ifdef _MSC_VER
# define restrict __restrict
# include <lzma.h>
# undef restrict
#define restrict __restrict
#include <lzma.h>
#undef restrict
#else
# include <lzma.h>
#include <lzma.h>
#endif
using namespace std;
#define MAX_BUF_SIZE 262144
#define MAX_BUF_SIZE 262144
#define READ_BUF_SIZE 32768
/* ------------------------------------------------------------------------ */
@ -48,10 +48,7 @@ public:
inline bool init_decoder()
{
lzma_ret ret = lzma_stream_decoder(
&strm,
200 * 1024 * 1024,
0);
lzma_ret ret = lzma_stream_decoder(&strm, 200 * 1024 * 1024, 0);
initialized = (ret == LZMA_OK);
return initialized;
}
@ -82,7 +79,7 @@ public:
struct bspatch_stream {
void *opaque;
int (*read)(const struct bspatch_stream *stream, void *buffer,
int length);
int length);
};
/* ------------------------------------------------------------------------ */
@ -116,7 +113,7 @@ static int64_t offtin(const uint8_t *buf)
/* ------------------------------------------------------------------------ */
static int bspatch(const uint8_t *old, int64_t oldsize, uint8_t *newp,
int64_t newsize, struct bspatch_stream *stream)
int64_t newsize, struct bspatch_stream *stream)
{
uint8_t buf[8];
int64_t oldpos, newpos;
@ -169,9 +166,9 @@ static int bspatch(const uint8_t *old, int64_t oldsize, uint8_t *newp,
/* ------------------------------------------------------------------------ */
struct patch_data {
HANDLE h;
lzma_stream *strm;
uint8_t buf[READ_BUF_SIZE];
HANDLE h;
lzma_stream *strm;
uint8_t buf[READ_BUF_SIZE];
};
static int read_lzma(const struct bspatch_stream *stream, void *buffer, int len)
@ -179,24 +176,24 @@ static int read_lzma(const struct bspatch_stream *stream, void *buffer, int len)
if (!len)
return 0;
patch_data *data = (patch_data*)stream->opaque;
HANDLE h = data->h;
lzma_stream *strm = data->strm;
patch_data *data = (patch_data *)stream->opaque;
HANDLE h = data->h;
lzma_stream *strm = data->strm;
strm->avail_out = (size_t)len;
strm->next_out = (uint8_t *)buffer;
strm->next_out = (uint8_t *)buffer;
for (;;) {
if (strm->avail_in == 0) {
DWORD read_size;
if (!ReadFile(h, data->buf, READ_BUF_SIZE, &read_size,
nullptr))
nullptr))
return -1;
if (read_size == 0)
return -1;
strm->avail_in = (size_t)read_size;
strm->next_in = data->buf;
strm->next_in = data->buf;
}
lzma_ret ret = lzma_code(strm, LZMA_RUN);
@ -213,25 +210,25 @@ static int read_lzma(const struct bspatch_stream *stream, void *buffer, int len)
int ApplyPatch(const wchar_t *patchFile, const wchar_t *targetFile)
try {
uint8_t header[24];
int64_t newsize;
uint8_t header[24];
int64_t newsize;
struct bspatch_stream stream;
bool success;
bool success;
WinHandle hPatch;
WinHandle hTarget;
WinHandle hPatch;
WinHandle hTarget;
LZMAStream strm;
/* --------------------------------- *
* open patch and file to patch */
hPatch = CreateFile(patchFile, GENERIC_READ, 0, nullptr,
OPEN_EXISTING, 0, nullptr);
hPatch = CreateFile(patchFile, GENERIC_READ, 0, nullptr, OPEN_EXISTING,
0, nullptr);
if (!hPatch.Valid())
throw int(GetLastError());
hTarget = CreateFile(targetFile, GENERIC_READ, 0, nullptr,
OPEN_EXISTING, 0, nullptr);
OPEN_EXISTING, 0, nullptr);
if (!hTarget.Valid())
throw int(GetLastError());
@ -289,14 +286,14 @@ try {
throw int(-10);
patch_data data;
data.h = hPatch;
data.h = hPatch;
data.strm = strm.get();
stream.read = read_lzma;
stream.read = read_lzma;
stream.opaque = &data;
int ret = bspatch(oldData.data(), oldData.size(), newData.data(),
newData.size(), &stream);
newData.size(), &stream);
if (ret != 0)
throw int(-9);
@ -305,14 +302,14 @@ try {
hTarget = nullptr;
hTarget = CreateFile(targetFile, GENERIC_WRITE, 0, nullptr,
CREATE_ALWAYS, 0, nullptr);
CREATE_ALWAYS, 0, nullptr);
if (!hTarget.Valid())
throw int(GetLastError());
DWORD written;
success = !!WriteFile(hTarget, newData.data(), (DWORD)newsize,
&written, nullptr);
success = !!WriteFile(hTarget, newData.data(), (DWORD)newsize, &written,
nullptr);
if (!success || written != newsize)
throw int(GetLastError());

View File

@ -2,20 +2,20 @@
// Microsoft Visual C++ generated include file.
// Used by updater.rc
//
#define IDD_UPDATEDIALOG 101
#define IDI_ICON1 103
#define IDC_PROGRESS 1001
#define IDC_STATUS 1002
#define IDCBUTTON 1004
#define IDC_BUTTON 1004
#define IDD_UPDATEDIALOG 101
#define IDI_ICON1 103
#define IDC_PROGRESS 1001
#define IDC_STATUS 1002
#define IDCBUTTON 1004
#define IDC_BUTTON 1004
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1005
#define _APS_NEXT_SYMED_VALUE 101
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1005
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -45,53 +45,44 @@
#define BLAKE2_HASH_STR_LENGTH ((BLAKE2_HASH_LENGTH * 2) + 1)
#if defined _M_IX86
#pragma comment(linker, \
"/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='x86' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='x86' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#elif defined _M_IA64
#pragma comment(linker, \
"/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='ia64' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='ia64' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#elif defined _M_X64
#pragma comment(linker, \
"/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='amd64' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='amd64' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#else
#pragma comment(linker, \
"/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' processorArchitecture='*' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' processorArchitecture='*' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#endif
#include <util/windows/WinHandle.hpp>
#include <jansson.h>
#include "resource.h"
bool HTTPGetFile(HINTERNET hConnect,
const wchar_t *url,
const wchar_t *outputPath,
const wchar_t *extraHeaders,
int * responseCode);
bool HTTPPostData(const wchar_t *url,
const BYTE * data,
int dataLen,
const wchar_t *extraHeaders,
int * responseCode,
std::string & response);
bool HTTPGetFile(HINTERNET hConnect, const wchar_t *url,
const wchar_t *outputPath, const wchar_t *extraHeaders,
int *responseCode);
bool HTTPPostData(const wchar_t *url, const BYTE *data, int dataLen,
const wchar_t *extraHeaders, int *responseCode,
std::string &response);
void HashToString(const BYTE *in, wchar_t *out);
void StringToHash(const wchar_t *in, BYTE *out);
@ -100,17 +91,17 @@ bool CalculateFileHash(const wchar_t *path, BYTE *hash);
int ApplyPatch(LPCTSTR patchFile, LPCTSTR targetFile);
extern HWND hwndMain;
extern HWND hwndMain;
extern HCRYPTPROV hProvider;
extern int totalFileSize;
extern int completedFileSize;
extern HANDLE cancelRequested;
extern int totalFileSize;
extern int completedFileSize;
extern HANDLE cancelRequested;
#pragma pack(push, r1, 1)
typedef struct {
BLOBHEADER blobheader;
RSAPUBKEY rsapubkey;
RSAPUBKEY rsapubkey;
} PUBLICKEYHEADER;
#pragma pack(pop, r1)

View File

@ -23,9 +23,9 @@ public:
freefunc(handle);
}
inline T *operator&() {return &handle;}
inline operator T() const {return handle;}
inline T get() const {return handle;}
inline T *operator&() { return &handle; }
inline operator T() const { return handle; }
inline T get() const { return handle; }
inline CustomHandle<T, freefunc> &operator=(T in)
{
@ -35,7 +35,7 @@ public:
return *this;
}
inline bool operator!() const {return !handle;}
inline bool operator!() const { return !handle; }
};
void FreeProvider(HCRYPTPROV prov);
@ -43,8 +43,8 @@ void FreeHash(HCRYPTHASH hash);
void FreeKey(HCRYPTKEY key);
using CryptProvider = CustomHandle<HCRYPTPROV, FreeProvider>;
using CryptHash = CustomHandle<HCRYPTHASH, FreeHash>;
using CryptKey = CustomHandle<HCRYPTKEY, FreeKey>;
using CryptHash = CustomHandle<HCRYPTHASH, FreeHash>;
using CryptKey = CustomHandle<HCRYPTKEY, FreeKey>;
/* ------------------------------------------------------------------------ */
@ -58,13 +58,13 @@ public:
LocalFree(ptr);
}
inline T **operator&() {return &ptr;}
inline operator T() const {return ptr;}
inline T *get() const {return ptr;}
inline T **operator&() { return &ptr; }
inline operator T() const { return ptr; }
inline T *get() const { return ptr; }
inline bool operator!() const {return !ptr;}
inline bool operator!() const { return !ptr; }
inline T *operator->() {return ptr;}
inline T *operator->() { return ptr; }
};
/* ------------------------------------------------------------------------ */
@ -76,9 +76,10 @@ public:
inline Json() : json(nullptr) {}
explicit inline Json(json_t *json_) : json(json_) {}
inline Json(const Json &from) : json(json_incref(from.json)) {}
inline Json(Json &&from) : json(from.json) {from.json = nullptr;}
inline Json(Json &&from) : json(from.json) { from.json = nullptr; }
inline ~Json() {
inline ~Json()
{
if (json)
json_decref(json);
}
@ -106,12 +107,12 @@ public:
return *this;
}
inline operator json_t *() const {return json;}
inline operator json_t *() const { return json; }
inline bool operator!() const {return !json;}
inline bool operator!() const { return !json; }
inline const char *GetString(const char *name,
const char *def = nullptr) const
const char *def = nullptr) const
{
json_t *obj(json_object_get(json, name));
if (!obj)
@ -130,7 +131,7 @@ public:
return json_object_get(json, name);
}
inline json_t *get() const {return json;}
inline json_t *get() const { return json; }
};
/* ------------------------------------------------------------------------ */

View File

@ -42,7 +42,7 @@ static __declspec(thread) HCRYPTPROV provider = 0;
typedef struct {
BLOBHEADER blobheader;
RSAPUBKEY rsapubkey;
RSAPUBKEY rsapubkey;
} PUBLICKEYHEADER;
#pragma pack(pop, r1)
@ -120,8 +120,7 @@ static const unsigned char obs_pub[] = {
0x42, 0x61, 0x35, 0x66, 0x37, 0x4c, 0x6f, 0x4b, 0x38, 0x43, 0x41, 0x77,
0x45, 0x41, 0x41, 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
0x45, 0x4e, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b,
0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a
};
0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a};
static const unsigned int obs_pub_len = 800;
/* ------------------------------------------------------------------------ */
@ -132,23 +131,18 @@ try {
if (os_utf8_to_wcs_ptr(file, 0, &w_file) == 0)
return false;
WinHandle handle = CreateFileW(
w_file,
GENERIC_WRITE,
0,
nullptr,
CREATE_ALWAYS,
FILE_FLAG_WRITE_THROUGH,
nullptr);
WinHandle handle = CreateFileW(w_file, GENERIC_WRITE, 0, nullptr,
CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH,
nullptr);
if (handle == INVALID_HANDLE_VALUE)
throw strprintf("Failed to open file '%s': %lu",
file, GetLastError());
throw strprintf("Failed to open file '%s': %lu", file,
GetLastError());
DWORD written;
if (!WriteFile(handle, data, (DWORD)size, &written, nullptr))
throw strprintf("Failed to write file '%s': %lu",
file, GetLastError());
throw strprintf("Failed to write file '%s': %lu", file,
GetLastError());
return true;
@ -163,26 +157,20 @@ try {
if (os_utf8_to_wcs_ptr(file, 0, &w_file) == 0)
return false;
WinHandle handle = CreateFileW(
w_file,
GENERIC_READ,
FILE_SHARE_READ,
nullptr,
OPEN_EXISTING,
0,
nullptr);
WinHandle handle = CreateFileW(w_file, GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
throw strprintf("Failed to open file '%s': %lu",
file, GetLastError());
throw strprintf("Failed to open file '%s': %lu", file,
GetLastError());
DWORD size = GetFileSize(handle, nullptr);
data.resize(size);
DWORD read;
if (!ReadFile(handle, &data[0], size, &read, nullptr))
throw strprintf("Failed to write file '%s': %lu",
file, GetLastError());
throw strprintf("Failed to write file '%s': %lu", file,
GetLastError());
return true;
@ -196,7 +184,7 @@ static void HashToString(const uint8_t *in, char *out)
const char alphabet[] = "0123456789abcdef";
for (int i = 0; i != BLAKE2_HASH_LENGTH; ++i) {
out[2 * i] = alphabet[in[i] / 16];
out[2 * i] = alphabet[in[i] / 16];
out[2 * i + 1] = alphabet[in[i] % 16];
}
@ -214,10 +202,10 @@ try {
return false;
WinHandle handle = CreateFileW(w_path, GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, 0, nullptr);
nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
throw strprintf("Failed to open file '%s': %lu",
path, GetLastError());
throw strprintf("Failed to open file '%s': %lu", path,
GetLastError());
vector<BYTE> buf;
buf.resize(65536);
@ -225,9 +213,9 @@ try {
for (;;) {
DWORD read = 0;
if (!ReadFile(handle, buf.data(), (DWORD)buf.size(), &read,
nullptr))
throw strprintf("Failed to read file '%s': %lu",
path, GetLastError());
nullptr))
throw strprintf("Failed to read file '%s': %lu", path,
GetLastError());
if (!read)
break;
@ -249,19 +237,19 @@ try {
/* ------------------------------------------------------------------------ */
static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig,
size_t sigLen)
size_t sigLen)
{
/* ASN of PEM public key */
BYTE binaryKey[1024];
BYTE binaryKey[1024];
DWORD binaryKeyLen = sizeof(binaryKey);
/* Windows X509 public key info from ASN */
LocalPtr<CERT_PUBLIC_KEY_INFO> publicPBLOB;
DWORD iPBLOBSize;
DWORD iPBLOBSize;
/* RSA BLOB info from X509 public key */
LocalPtr<PUBLICKEYHEADER> rsaPublicBLOB;
DWORD rsaPublicBLOBSize;
DWORD rsaPublicBLOBSize;
/* Handle to public key */
CryptKey keyOut;
@ -272,41 +260,26 @@ static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig,
/* Signature in little-endian format */
vector<BYTE> reversedSig;
if (!CryptStringToBinaryA((LPCSTR)obs_pub,
obs_pub_len,
CRYPT_STRING_BASE64HEADER,
binaryKey,
&binaryKeyLen,
nullptr,
nullptr))
if (!CryptStringToBinaryA((LPCSTR)obs_pub, obs_pub_len,
CRYPT_STRING_BASE64HEADER, binaryKey,
&binaryKeyLen, nullptr, nullptr))
return false;
if (!CryptDecodeObjectEx(X509_ASN_ENCODING,
X509_PUBLIC_KEY_INFO,
binaryKey,
binaryKeyLen,
CRYPT_ENCODE_ALLOC_FLAG,
nullptr,
&publicPBLOB,
&iPBLOBSize))
if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
binaryKey, binaryKeyLen,
CRYPT_ENCODE_ALLOC_FLAG, nullptr, &publicPBLOB,
&iPBLOBSize))
return false;
if (!CryptDecodeObjectEx(X509_ASN_ENCODING,
RSA_CSP_PUBLICKEYBLOB,
publicPBLOB->PublicKey.pbData,
publicPBLOB->PublicKey.cbData,
CRYPT_ENCODE_ALLOC_FLAG,
nullptr,
&rsaPublicBLOB,
&rsaPublicBLOBSize))
if (!CryptDecodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
publicPBLOB->PublicKey.pbData,
publicPBLOB->PublicKey.cbData,
CRYPT_ENCODE_ALLOC_FLAG, nullptr,
&rsaPublicBLOB, &rsaPublicBLOBSize))
return false;
if (!CryptImportKey(provider,
(const BYTE *)rsaPublicBLOB.get(),
rsaPublicBLOBSize,
0,
0,
&keyOut))
if (!CryptImportKey(provider, (const BYTE *)rsaPublicBLOB.get(),
rsaPublicBLOBSize, 0, 0, &keyOut))
return false;
if (!CryptCreateHash(provider, CALG_SHA_512, 0, 0, &hash))
@ -321,19 +294,15 @@ static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig,
for (size_t i = 0; i < sigLen; i++)
reversedSig[i] = sig[sigLen - i - 1];
if (!CryptVerifySignature(hash,
reversedSig.data(),
(DWORD)sigLen,
keyOut,
nullptr,
0))
if (!CryptVerifySignature(hash, reversedSig.data(), (DWORD)sigLen,
keyOut, nullptr, 0))
return false;
return true;
}
static inline void HexToByteArray(const char *hexStr, size_t hexLen,
vector<uint8_t> &out)
vector<uint8_t> &out)
{
char ptr[3];
@ -347,7 +316,7 @@ static inline void HexToByteArray(const char *hexStr, size_t hexLen,
}
static bool CheckDataSignature(const string &data, const char *name,
const char *hexSig, size_t sigLen)
const char *hexSig, size_t sigLen)
try {
if (sigLen == 0 || sigLen > 0xFFFF || (sigLen & 1) != 0)
throw strprintf("Missing or invalid signature for %s", name);
@ -357,10 +326,8 @@ try {
signature.reserve(sigLen);
HexToByteArray(hexSig, sigLen, signature);
if (!VerifyDigitalSignature((uint8_t*)data.data(),
data.size(),
signature.data(),
signature.size()))
if (!VerifyDigitalSignature((uint8_t *)data.data(), data.size(),
signature.data(), signature.size()))
throw strprintf("Signature check failed for %s", name);
return true;
@ -374,12 +341,12 @@ try {
static bool FetchUpdaterModule(const char *url)
try {
long responseCode;
uint8_t updateFileHash[BLAKE2_HASH_LENGTH];
long responseCode;
uint8_t updateFileHash[BLAKE2_HASH_LENGTH];
vector<string> extraHeaders;
BPtr<char> updateFilePath = GetConfigPathPtr(
"obs-studio\\updates\\updater.exe");
BPtr<char> updateFilePath =
GetConfigPathPtr("obs-studio\\updates\\updater.exe");
if (CalculateFileHash(updateFilePath, updateFileHash)) {
char hashString[BLAKE2_HASH_STR_LENGTH];
@ -394,8 +361,8 @@ try {
string error;
string data;
bool success = GetRemoteFile(url, data, error, &responseCode,
nullptr, nullptr, extraHeaders, &signature);
bool success = GetRemoteFile(url, data, error, &responseCode, nullptr,
nullptr, extraHeaders, &signature);
if (!success || (responseCode != 200 && responseCode != 304)) {
if (responseCode == 404)
@ -407,7 +374,7 @@ try {
/* A new file must be digitally signed */
if (responseCode == 200) {
bool valid = CheckDataSignature(data, url, signature.data(),
signature.size());
signature.size());
if (!valid)
throw string("Invalid updater module signature");
@ -425,7 +392,7 @@ try {
/* ------------------------------------------------------------------------ */
static bool ParseUpdateManifest(const char *manifest, bool *updatesAvailable,
string &notes_str, int &updateVer)
string &notes_str, int &updateVer)
try {
json_error_t error;
@ -442,10 +409,8 @@ try {
int patch = root.GetInt("version_patch");
if (major == 0)
throw strprintf("Invalid version number: %d.%d.%d",
major,
minor,
patch);
throw strprintf("Invalid version number: %d.%d.%d", major,
minor, patch);
json_t *notes = json_object_get(root, "notes");
if (!json_is_string(notes))
@ -491,8 +456,8 @@ string GetProgramGUID()
/* NOTE: this is an arbitrary random number that we use to count the
* number of unique OBS installations and is not associated with any
* kind of identifiable information */
const char *pguid = config_get_string(GetGlobalConfig(),
"General", "InstallGUID");
const char *pguid =
config_get_string(GetGlobalConfig(), "General", "InstallGUID");
string guid;
if (pguid)
guid = pguid;
@ -501,9 +466,8 @@ string GetProgramGUID()
GenerateGUID(guid);
if (!guid.empty())
config_set_string(GetGlobalConfig(),
"General", "InstallGUID",
guid.c_str());
config_set_string(GetGlobalConfig(), "General",
"InstallGUID", guid.c_str());
}
return guid;
@ -516,13 +480,12 @@ void AutoUpdateThread::infoMsg(const QString &title, const QString &text)
void AutoUpdateThread::info(const QString &title, const QString &text)
{
QMetaObject::invokeMethod(this, "infoMsg",
Qt::BlockingQueuedConnection,
Q_ARG(QString, title),
Q_ARG(QString, text));
QMetaObject::invokeMethod(this, "infoMsg", Qt::BlockingQueuedConnection,
Q_ARG(QString, title), Q_ARG(QString, text));
}
int AutoUpdateThread::queryUpdateSlot(bool localManualUpdate, const QString &text)
int AutoUpdateThread::queryUpdateSlot(bool localManualUpdate,
const QString &text)
{
OBSUpdate updateDlg(App()->GetMainWindow(), localManualUpdate, text);
return updateDlg.exec();
@ -533,17 +496,17 @@ int AutoUpdateThread::queryUpdate(bool localManualUpdate, const char *text_utf8)
int ret = OBSUpdate::No;
QString text = text_utf8;
QMetaObject::invokeMethod(this, "queryUpdateSlot",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(int, ret),
Q_ARG(bool, localManualUpdate),
Q_ARG(QString, text));
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(int, ret),
Q_ARG(bool, localManualUpdate),
Q_ARG(QString, text));
return ret;
}
static bool IsFileInUse(const wstring &file)
{
WinHandle f = CreateFile(file.c_str(), GENERIC_WRITE, 0, nullptr,
OPEN_EXISTING, 0, nullptr);
OPEN_EXISTING, 0, nullptr);
if (!f.Valid()) {
int err = GetLastError();
if (err == ERROR_SHARING_VIOLATION ||
@ -557,35 +520,33 @@ static bool IsFileInUse(const wstring &file)
static bool IsGameCaptureInUse()
{
wstring path = L"..\\..\\data\\obs-plugins\\win-capture\\graphics-hook";
return IsFileInUse(path + L"32.dll") ||
IsFileInUse(path + L"64.dll");
return IsFileInUse(path + L"32.dll") || IsFileInUse(path + L"64.dll");
}
void AutoUpdateThread::run()
try {
long responseCode;
long responseCode;
vector<string> extraHeaders;
string text;
string error;
string signature;
CryptProvider localProvider;
BYTE manifestHash[BLAKE2_HASH_LENGTH];
bool updatesAvailable = false;
bool success;
string text;
string error;
string signature;
CryptProvider localProvider;
BYTE manifestHash[BLAKE2_HASH_LENGTH];
bool updatesAvailable = false;
bool success;
struct FinishedTrigger {
inline ~FinishedTrigger()
{
QMetaObject::invokeMethod(App()->GetMainWindow(),
"updateCheckFinished");
"updateCheckFinished");
}
} finishedTrigger;
BPtr<char> manifestPath = GetConfigPathPtr(
"obs-studio\\updates\\manifest.json");
BPtr<char> manifestPath =
GetConfigPathPtr("obs-studio\\updates\\manifest.json");
auto ActiveOrGameCaptureLocked = [this] ()
{
auto ActiveOrGameCaptureLocked = [this]() {
if (obs_video_active()) {
if (manualUpdate)
info(QTStr("Updater.Running.Title"),
@ -611,11 +572,8 @@ try {
/* ----------------------------------- *
* create signature provider */
if (!CryptAcquireContext(&localProvider,
nullptr,
MS_ENH_RSA_AES_PROV,
PROV_RSA_AES,
CRYPT_VERIFYCONTEXT))
if (!CryptAcquireContext(&localProvider, nullptr, MS_ENH_RSA_AES_PROV,
PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
throw strprintf("CryptAcquireContext failed: %lu",
GetLastError());
@ -647,13 +605,14 @@ try {
* get manifest from server */
success = GetRemoteFile(WIN_MANIFEST_URL, text, error, &responseCode,
nullptr, nullptr, extraHeaders, &signature);
nullptr, nullptr, extraHeaders, &signature);
if (!success || (responseCode != 200 && responseCode != 304)) {
if (responseCode == 404)
return;
throw strprintf("Failed to fetch manifest file: %s", error.c_str());
throw strprintf("Failed to fetch manifest file: %s",
error.c_str());
}
/* ----------------------------------- *
@ -661,8 +620,8 @@ try {
/* a new file must be digitally signed */
if (responseCode == 200) {
success = CheckDataSignature(text, "manifest",
signature.data(), signature.size());
success = CheckDataSignature(text, "manifest", signature.data(),
signature.size());
if (!success)
throw string("Invalid manifest signature");
}
@ -687,7 +646,7 @@ try {
int updateVer = 0;
success = ParseUpdateManifest(text.c_str(), &updatesAvailable, notes,
updateVer);
updateVer);
if (!success)
throw string("Failed to parse manifest");
@ -702,7 +661,7 @@ try {
* skip this version if set to skip */
int skipUpdateVer = config_get_int(GetGlobalConfig(), "General",
"SkipUpdateVersion");
"SkipUpdateVersion");
if (!manualUpdate && updateVer == skipUpdateVer)
return;
@ -727,13 +686,13 @@ try {
if (!manualUpdate) {
long long t = (long long)time(nullptr);
config_set_int(GetGlobalConfig(), "General",
"LastUpdateCheck", t);
"LastUpdateCheck", t);
}
return;
} else if (queryResult == OBSUpdate::Skip) {
config_set_int(GetGlobalConfig(), "General",
"SkipUpdateVersion", updateVer);
"SkipUpdateVersion", updateVer);
return;
}
@ -749,8 +708,8 @@ try {
/* ----------------------------------- *
* execute updater */
BPtr<char> updateFilePath = GetConfigPathPtr(
"obs-studio\\updates\\updater.exe");
BPtr<char> updateFilePath =
GetConfigPathPtr("obs-studio\\updates\\updater.exe");
BPtr<wchar_t> wUpdateFilePath;
size_t size = os_utf8_to_wcs_ptr(updateFilePath, 0, &wUpdateFilePath);
@ -773,7 +732,7 @@ try {
execInfo.lpParameters = UPDATE_ARG_SUFFIX;
execInfo.lpDirectory = cwd;
execInfo.nShow = SW_SHOWNORMAL;
execInfo.nShow = SW_SHOWNORMAL;
if (!ShellExecuteEx(&execInfo)) {
QString msg = QTStr("Updater.FailedToLaunch");
@ -787,7 +746,7 @@ try {
config_set_int(GetGlobalConfig(), "General", "LastUpdateCheck", 0);
config_set_int(GetGlobalConfig(), "General", "SkipUpdateVersion", 0);
config_set_string(GetGlobalConfig(), "General", "InstallGUID",
guid.c_str());
guid.c_str());
QMetaObject::invokeMethod(App()->GetMainWindow(), "close");
@ -799,26 +758,23 @@ try {
void WhatsNewInfoThread::run()
try {
long responseCode;
long responseCode;
vector<string> extraHeaders;
string text;
string error;
string signature;
CryptProvider localProvider;
BYTE whatsnewHash[BLAKE2_HASH_LENGTH];
bool success;
string text;
string error;
string signature;
CryptProvider localProvider;
BYTE whatsnewHash[BLAKE2_HASH_LENGTH];
bool success;
BPtr<char> whatsnewPath = GetConfigPathPtr(
"obs-studio\\updates\\whatsnew.json");
BPtr<char> whatsnewPath =
GetConfigPathPtr("obs-studio\\updates\\whatsnew.json");
/* ----------------------------------- *
* create signature provider */
if (!CryptAcquireContext(&localProvider,
nullptr,
MS_ENH_RSA_AES_PROV,
PROV_RSA_AES,
CRYPT_VERIFYCONTEXT))
if (!CryptAcquireContext(&localProvider, nullptr, MS_ENH_RSA_AES_PROV,
PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
throw strprintf("CryptAcquireContext failed: %lu",
GetLastError());
@ -851,7 +807,7 @@ try {
* get json from server */
success = GetRemoteFile(WIN_WHATSNEW_URL, text, error, &responseCode,
nullptr, nullptr, extraHeaders, &signature);
nullptr, nullptr, extraHeaders, &signature);
if (!success || (responseCode != 200 && responseCode != 304)) {
if (responseCode == 404)
@ -865,8 +821,8 @@ try {
* verify file signature */
if (responseCode == 200) {
success = CheckDataSignature(text, "whatsnew",
signature.data(), signature.size());
success = CheckDataSignature(text, "whatsnew", signature.data(),
signature.size());
if (!success)
throw string("Invalid whatsnew signature");
}

View File

@ -9,9 +9,7 @@
using namespace json11;
OBSAbout::OBSAbout(QWidget *parent)
: QDialog(parent),
ui(new Ui::OBSAbout)
OBSAbout::OBSAbout(QWidget *parent) : QDialog(parent), ui(new Ui::OBSAbout)
{
ui->setupUi(this);
@ -20,29 +18,30 @@ OBSAbout::OBSAbout(QWidget *parent)
QString bitness;
QString ver;
if(sizeof(void*) == 4)
if (sizeof(void *) == 4)
bitness = " (32 bit)";
else if(sizeof(void*) == 8)
else if (sizeof(void *) == 8)
bitness = " (64 bit)";
#ifdef HAVE_OBSCONFIG_H
ver += OBS_VERSION;
ver += OBS_VERSION;
#else
ver += LIBOBS_API_MAJOR_VER + "." +
LIBOBS_API_MINOR_VER + "." +
LIBOBS_API_PATCH_VER;
ver += LIBOBS_API_MAJOR_VER + "." + LIBOBS_API_MINOR_VER + "." +
LIBOBS_API_PATCH_VER;
#endif
ui->version->setText(ver + bitness);
ui->contribute->setText(QTStr("About.Contribute"));
ui->donate->setText("&nbsp;&nbsp;<a href='https://obsproject.com/donate'>" +
QTStr("About.Donate") + "</a>");
ui->donate->setText(
"&nbsp;&nbsp;<a href='https://obsproject.com/donate'>" +
QTStr("About.Donate") + "</a>");
ui->donate->setTextInteractionFlags(Qt::TextBrowserInteraction);
ui->donate->setOpenExternalLinks(true);
ui->getInvolved->setText("&nbsp;&nbsp;<a href='https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.rst'>" +
QTStr("About.GetInvolved") + "</a>");
ui->getInvolved->setText(
"&nbsp;&nbsp;<a href='https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.rst'>" +
QTStr("About.GetInvolved") + "</a>");
ui->getInvolved->setTextInteractionFlags(Qt::TextBrowserInteraction);
ui->getInvolved->setOpenExternalLinks(true);
@ -66,12 +65,14 @@ OBSAbout::OBSAbout(QWidget *parent)
OBSBasic *main = OBSBasic::Get();
if (main->patronJson.empty() && !main->patronJsonThread) {
RemoteTextThread *thread = new RemoteTextThread(
"https://obsproject.com/patreon/about-box.json",
"application/json");
QObject::connect(thread, &RemoteTextThread::Result,
main, &OBSBasic::UpdatePatronJson);
QObject::connect(thread, SIGNAL(Result(const QString &, const QString &)),
this, SLOT(ShowAbout()));
"https://obsproject.com/patreon/about-box.json",
"application/json");
QObject::connect(thread, &RemoteTextThread::Result, main,
&OBSBasic::UpdatePatronJson);
QObject::connect(
thread,
SIGNAL(Result(const QString &, const QString &)), this,
SLOT(ShowAbout()));
main->patronJsonThread.reset(thread);
thread->start();
} else {

View File

@ -16,9 +16,9 @@ Q_DECLARE_METATYPE(OBSSource);
OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent)
: QDialog(parent),
sourceAddedSignal(obs_get_signal_handler(), "source_activate",
OBSSourceAdded, this),
OBSSourceAdded, this),
sourceRemovedSignal(obs_get_signal_handler(), "source_deactivate",
OBSSourceRemoved, this)
OBSSourceRemoved, this)
{
QScrollArea *scrollArea;
QVBoxLayout *vlayout;
@ -55,7 +55,7 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent)
controlArea = new QWidget;
controlArea->setLayout(mainLayout);
controlArea->setSizePolicy(QSizePolicy::Preferred,
QSizePolicy::Preferred);
QSizePolicy::Preferred);
vlayout = new QVBoxLayout;
vlayout->addWidget(controlArea);
@ -80,7 +80,7 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent)
vlayout->addLayout(buttonLayout);
setLayout(vlayout);
connect(closeButton, &QPushButton::clicked, [this] () {close();});
connect(closeButton, &QPushButton::clicked, [this]() { close(); });
installEventFilter(CreateShortcutFilter());
@ -97,7 +97,7 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent)
OBSBasicAdvAudio::~OBSBasicAdvAudio()
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(parent());
OBSBasic *main = reinterpret_cast<OBSBasic *>(parent());
for (size_t i = 0; i < controls.size(); ++i)
delete controls[i];
@ -107,7 +107,7 @@ OBSBasicAdvAudio::~OBSBasicAdvAudio()
bool OBSBasicAdvAudio::EnumSources(void *param, obs_source_t *source)
{
OBSBasicAdvAudio *dialog = reinterpret_cast<OBSBasicAdvAudio*>(param);
OBSBasicAdvAudio *dialog = reinterpret_cast<OBSBasicAdvAudio *>(param);
uint32_t flags = obs_source_get_output_flags(source);
if ((flags & OBS_SOURCE_AUDIO) != 0 && obs_source_active(source))
@ -118,18 +118,18 @@ bool OBSBasicAdvAudio::EnumSources(void *param, obs_source_t *source)
void OBSBasicAdvAudio::OBSSourceAdded(void *param, calldata_t *calldata)
{
OBSSource source((obs_source_t*)calldata_ptr(calldata, "source"));
OBSSource source((obs_source_t *)calldata_ptr(calldata, "source"));
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicAdvAudio*>(param),
"SourceAdded", Q_ARG(OBSSource, source));
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicAdvAudio *>(param),
"SourceAdded", Q_ARG(OBSSource, source));
}
void OBSBasicAdvAudio::OBSSourceRemoved(void *param, calldata_t *calldata)
{
OBSSource source((obs_source_t*)calldata_ptr(calldata, "source"));
OBSSource source((obs_source_t *)calldata_ptr(calldata, "source"));
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicAdvAudio*>(param),
"SourceRemoved", Q_ARG(OBSSource, source));
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicAdvAudio *>(param),
"SourceRemoved", Q_ARG(OBSSource, source));
}
inline void OBSBasicAdvAudio::AddAudioSource(obs_source_t *source)

View File

@ -18,7 +18,7 @@ private:
OBSSignal sourceAddedSignal;
OBSSignal sourceRemovedSignal;
std::vector<OBSAdvAudioCtrl*> controls;
std::vector<OBSAdvAudioCtrl *> controls;
inline void AddAudioSource(obs_source_t *source);

View File

@ -15,7 +15,7 @@
#include "ui_AutoConfigTestPage.h"
#define wiz reinterpret_cast<AutoConfig*>(wizard())
#define wiz reinterpret_cast<AutoConfig *>(wizard())
using namespace std;
@ -31,17 +31,14 @@ class TestMode {
gs_eparam_t *randomvals[3] = {
gs_effect_get_param_by_name(solid, "randomvals1"),
gs_effect_get_param_by_name(solid, "randomvals2"),
gs_effect_get_param_by_name(solid, "randomvals3")
};
gs_effect_get_param_by_name(solid, "randomvals3")};
struct vec4 r;
for (int i = 0; i < 3; i++) {
vec4_set(&r,
rand_float(true) * 100.0f,
rand_float(true) * 100.0f,
rand_float(true) * 50000.0f + 10000.0f,
0.0f);
vec4_set(&r, rand_float(true) * 100.0f,
rand_float(true) * 100.0f,
rand_float(true) * 50000.0f + 10000.0f, 0.0f);
gs_effect_set_vec4(randomvals[i], &r);
}
@ -86,37 +83,37 @@ public:
/* ------------------------------------------------------------------------- */
#define TEST_STR(x) "Basic.AutoConfig.TestPage." x
#define SUBTITLE_TESTING TEST_STR("Subtitle.Testing")
#define SUBTITLE_COMPLETE TEST_STR("Subtitle.Complete")
#define TEST_BW TEST_STR("TestingBandwidth")
#define TEST_BW_CONNECTING TEST_STR("TestingBandwidth.Connecting")
#define TEST_BW_CONNECT_FAIL TEST_STR("TestingBandwidth.ConnectFailed")
#define TEST_BW_SERVER TEST_STR("TestingBandwidth.Server")
#define TEST_RES TEST_STR("TestingRes")
#define TEST_RES_VAL TEST_STR("TestingRes.Resolution")
#define TEST_RES_FAIL TEST_STR("TestingRes.Fail")
#define TEST_SE TEST_STR("TestingStreamEncoder")
#define TEST_RE TEST_STR("TestingRecordingEncoder")
#define TEST_RESULT_SE TEST_STR("Result.StreamingEncoder")
#define TEST_RESULT_RE TEST_STR("Result.RecordingEncoder")
#define TEST_STR(x) "Basic.AutoConfig.TestPage." x
#define SUBTITLE_TESTING TEST_STR("Subtitle.Testing")
#define SUBTITLE_COMPLETE TEST_STR("Subtitle.Complete")
#define TEST_BW TEST_STR("TestingBandwidth")
#define TEST_BW_CONNECTING TEST_STR("TestingBandwidth.Connecting")
#define TEST_BW_CONNECT_FAIL TEST_STR("TestingBandwidth.ConnectFailed")
#define TEST_BW_SERVER TEST_STR("TestingBandwidth.Server")
#define TEST_RES TEST_STR("TestingRes")
#define TEST_RES_VAL TEST_STR("TestingRes.Resolution")
#define TEST_RES_FAIL TEST_STR("TestingRes.Fail")
#define TEST_SE TEST_STR("TestingStreamEncoder")
#define TEST_RE TEST_STR("TestingRecordingEncoder")
#define TEST_RESULT_SE TEST_STR("Result.StreamingEncoder")
#define TEST_RESULT_RE TEST_STR("Result.RecordingEncoder")
void AutoConfigTestPage::StartBandwidthStage()
{
ui->progressLabel->setText(QTStr(TEST_BW));
testThread = std::thread([this] () {TestBandwidthThread();});
testThread = std::thread([this]() { TestBandwidthThread(); });
}
void AutoConfigTestPage::StartStreamEncoderStage()
{
ui->progressLabel->setText(QTStr(TEST_SE));
testThread = std::thread([this] () {TestStreamEncoderThread();});
testThread = std::thread([this]() { TestStreamEncoderThread(); });
}
void AutoConfigTestPage::StartRecordingEncoderStage()
{
ui->progressLabel->setText(QTStr(TEST_RE));
testThread = std::thread([this] () {TestRecordingEncoderThread();});
testThread = std::thread([this]() { TestRecordingEncoderThread(); });
}
void AutoConfigTestPage::GetServers(std::vector<ServerInfo> &servers)
@ -176,21 +173,20 @@ void AutoConfigTestPage::TestBandwidthThread()
*/
QMetaObject::invokeMethod(this, "UpdateMessage",
Q_ARG(QString, QStringLiteral("")));
Q_ARG(QString, QStringLiteral("")));
/* -----------------------------------*/
/* create obs objects */
const char *serverType = wiz->customServer
? "rtmp_custom"
: "rtmp_common";
const char *serverType = wiz->customServer ? "rtmp_custom"
: "rtmp_common";
OBSEncoder vencoder = obs_video_encoder_create("obs_x264",
"test_x264", nullptr, nullptr);
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac",
"test_aac", nullptr, 0, nullptr);
OBSService service = obs_service_create(serverType,
"test_service", nullptr, nullptr);
OBSEncoder vencoder = obs_video_encoder_create("obs_x264", "test_x264",
nullptr, nullptr);
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", "test_aac",
nullptr, 0, nullptr);
OBSService service = obs_service_create(serverType, "test_service",
nullptr, nullptr);
obs_encoder_release(vencoder);
obs_encoder_release(aencoder);
obs_service_release(service);
@ -218,14 +214,14 @@ void AutoConfigTestPage::TestBandwidthThread()
if (wiz->service == AutoConfig::Service::Twitch) {
string_depad_key(key);
key += "?bandwidthtest";
}
else if(wiz->serviceName == "Restream.io" || wiz->serviceName == "Restream.io - RTMP") {
} else if (wiz->serviceName == "Restream.io" ||
wiz->serviceName == "Restream.io - RTMP") {
string_depad_key(key);
key += "?test=true";
}
obs_data_set_string(service_settings, "service",
wiz->serviceName.c_str());
wiz->serviceName.c_str());
obs_data_set_string(service_settings, "key", key.c_str());
obs_data_set_int(vencoder_settings, "bitrate", wiz->startingBitrate);
@ -235,9 +231,9 @@ void AutoConfigTestPage::TestBandwidthThread()
obs_data_set_int(aencoder_settings, "bitrate", 32);
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
const char *bind_ip = config_get_string(main->Config(), "Output",
"BindIP");
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
const char *bind_ip =
config_get_string(main->Config(), "Output", "BindIP");
obs_data_set_string(output_settings, "bind_ip", bind_ip);
/* -----------------------------------*/
@ -251,12 +247,12 @@ void AutoConfigTestPage::TestBandwidthThread()
/* just use the first server if it only has one alternate server,
* or if using Mixer or Restream due to their "auto" servers */
if (servers.size() < 3 || wiz->serviceName == "Mixer.com - FTL" ||
wiz->serviceName.substr(0, 11)=="Restream.io") {
if (servers.size() < 3 || wiz->serviceName == "Mixer.com - FTL" ||
wiz->serviceName.substr(0, 11) == "Restream.io") {
servers.resize(1);
} else if (wiz->service == AutoConfig::Service::Twitch &&
wiz->twitchAuto) {
wiz->twitchAuto) {
/* if using Twitch and "Auto" is available, test 3 closest
* server */
servers.erase(servers.begin() + 1);
@ -267,8 +263,8 @@ void AutoConfigTestPage::TestBandwidthThread()
/* apply service settings */
obs_service_update(service, service_settings);
obs_service_apply_encoder_settings(service,
vencoder_settings, aencoder_settings);
obs_service_apply_encoder_settings(service, vencoder_settings,
aencoder_settings);
/* -----------------------------------*/
/* create output */
@ -277,18 +273,17 @@ void AutoConfigTestPage::TestBandwidthThread()
if (!output_type)
output_type = "rtmp_output";
OBSOutput output = obs_output_create(output_type,
"test_stream", nullptr, nullptr);
OBSOutput output =
obs_output_create(output_type, "test_stream", nullptr, nullptr);
obs_output_release(output);
obs_output_update(output, output_settings);
const char *audio_codec =
obs_output_get_supported_audio_codecs(output);
const char *audio_codec = obs_output_get_supported_audio_codecs(output);
if (strcmp(audio_codec, "aac") != 0) {
const char *id = FindAudioEncoderFromCodec(audio_codec);
aencoder = obs_audio_encoder_create(id,
"test_audio", nullptr, 0, nullptr);
aencoder = obs_audio_encoder_create(id, "test_audio", nullptr,
0, nullptr);
obs_encoder_release(aencoder);
}
@ -308,16 +303,14 @@ void AutoConfigTestPage::TestBandwidthThread()
/* -----------------------------------*/
/* connect signals */
auto on_started = [&] ()
{
auto on_started = [&]() {
unique_lock<mutex> lock(m);
connected = true;
stopped = false;
cv.notify_one();
};
auto on_stopped = [&] ()
{
auto on_stopped = [&]() {
unique_lock<mutex> lock(m);
connected = false;
stopped = true;
@ -327,17 +320,15 @@ void AutoConfigTestPage::TestBandwidthThread()
using on_started_t = decltype(on_started);
using on_stopped_t = decltype(on_stopped);
auto pre_on_started = [] (void *data, calldata_t *)
{
auto pre_on_started = [](void *data, calldata_t *) {
on_started_t &on_started =
*reinterpret_cast<on_started_t*>(data);
*reinterpret_cast<on_started_t *>(data);
on_started();
};
auto pre_on_stopped = [] (void *data, calldata_t *)
{
auto pre_on_stopped = [](void *data, calldata_t *) {
on_stopped_t &on_stopped =
*reinterpret_cast<on_stopped_t*>(data);
*reinterpret_cast<on_stopped_t *>(data);
on_stopped();
};
@ -358,12 +349,13 @@ void AutoConfigTestPage::TestBandwidthThread()
int per = int((i + 1) * 100 / servers.size());
QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, per));
QMetaObject::invokeMethod(this, "UpdateMessage",
Q_ARG(QString, QTStr(TEST_BW_CONNECTING)
.arg(server.name.c_str())));
QMetaObject::invokeMethod(
this, "UpdateMessage",
Q_ARG(QString, QTStr(TEST_BW_CONNECTING)
.arg(server.name.c_str())));
obs_data_set_string(service_settings, "server",
server.address.c_str());
server.address.c_str());
obs_service_update(service, service_settings);
if (!obs_output_start(output))
@ -385,9 +377,10 @@ void AutoConfigTestPage::TestBandwidthThread()
if (!connected)
continue;
QMetaObject::invokeMethod(this, "UpdateMessage",
Q_ARG(QString, QTStr(TEST_BW_SERVER)
.arg(server.name.c_str())));
QMetaObject::invokeMethod(
this, "UpdateMessage",
Q_ARG(QString,
QTStr(TEST_BW_SERVER).arg(server.name.c_str())));
/* ignore first 2.5 seconds due to possible buffering skewing
* the result */
@ -418,10 +411,10 @@ void AutoConfigTestPage::TestBandwidthThread()
uint64_t total_time = os_gettime_ns() - t_start;
int total_bytes = (int)obs_output_get_total_bytes(output) -
start_bytes;
uint64_t bitrate = (uint64_t)total_bytes * 8
* 1000000000 / total_time / 1000;
int total_bytes =
(int)obs_output_get_total_bytes(output) - start_bytes;
uint64_t bitrate = (uint64_t)total_bytes * 8 * 1000000000 /
total_time / 1000;
if (obs_output_get_frames_dropped(output) ||
(int)bitrate < (wiz->startingBitrate * 75 / 100)) {
@ -436,7 +429,8 @@ void AutoConfigTestPage::TestBandwidthThread()
if (!success) {
QMetaObject::invokeMethod(this, "Failure",
Q_ARG(QString, QTStr(TEST_BW_CONNECT_FAIL)));
Q_ARG(QString,
QTStr(TEST_BW_CONNECT_FAIL)));
return;
}
@ -480,7 +474,8 @@ static long double EstimateMinBitrate(int cx, int cy, int fps_num, int fps_den)
return EstimateBitrateVal(cx, cy, fps_num, fps_den) / val;
}
static long double EstimateUpperBitrate(int cx, int cy, int fps_num, int fps_den)
static long double EstimateUpperBitrate(int cx, int cy, int fps_num,
int fps_den)
{
long double val = EstimateBitrateVal(1280, 720, 30, 1) / 3000.0l;
return EstimateBitrateVal(cx, cy, fps_num, fps_den) / val;
@ -520,17 +515,17 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
{
TestMode testMode;
QMetaObject::invokeMethod(this, "UpdateMessage",
Q_ARG(QString, QStringLiteral("")));
Q_ARG(QString, QStringLiteral("")));
/* -----------------------------------*/
/* create obs objects */
OBSEncoder vencoder = obs_video_encoder_create("obs_x264",
"test_x264", nullptr, nullptr);
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac",
"test_aac", nullptr, 0, nullptr);
OBSOutput output = obs_output_create("null_output",
"null", nullptr, nullptr);
OBSEncoder vencoder = obs_video_encoder_create("obs_x264", "test_x264",
nullptr, nullptr);
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", "test_aac",
nullptr, 0, nullptr);
OBSOutput output =
obs_output_create("null_output", "null", nullptr, nullptr);
obs_output_release(output);
obs_encoder_release(vencoder);
obs_encoder_release(aencoder);
@ -547,7 +542,7 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
if (wiz->type != AutoConfig::Type::Recording) {
obs_data_set_int(vencoder_settings, "keyint_sec", 2);
obs_data_set_int(vencoder_settings, "bitrate",
wiz->idealBitrate);
wiz->idealBitrate);
obs_data_set_string(vencoder_settings, "rate_control", "CBR");
obs_data_set_string(vencoder_settings, "profile", "main");
obs_data_set_string(vencoder_settings, "preset", "veryfast");
@ -573,18 +568,16 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
/* -----------------------------------*/
/* connect signals */
auto on_stopped = [&] ()
{
auto on_stopped = [&]() {
unique_lock<mutex> lock(m);
cv.notify_one();
};
using on_stopped_t = decltype(on_stopped);
auto pre_on_stopped = [] (void *data, calldata_t *)
{
auto pre_on_stopped = [](void *data, calldata_t *) {
on_stopped_t &on_stopped =
*reinterpret_cast<on_stopped_t*>(data);
*reinterpret_cast<on_stopped_t *>(data);
on_stopped();
};
@ -628,9 +621,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
int i = 0;
int count = 1;
auto testRes = [&] (long double div, int fps_num, int fps_den,
bool force)
{
auto testRes = [&](long double div, int fps_num, int fps_den,
bool force) {
int per = ++i * 100 / count;
QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, per));
@ -669,13 +661,13 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
QString cxStr = QString::number(cx);
QString cyStr = QString::number(cy);
QString fpsStr = (fps_den > 1)
? QString::number(fps, 'f', 2)
: QString::number(fps, 'g', 2);
QString fpsStr = (fps_den > 1) ? QString::number(fps, 'f', 2)
: QString::number(fps, 'g', 2);
QMetaObject::invokeMethod(this, "UpdateMessage",
Q_ARG(QString, QTStr(TEST_RES_VAL)
.arg(cxStr, cyStr, fpsStr)));
QMetaObject::invokeMethod(
this, "UpdateMessage",
Q_ARG(QString,
QTStr(TEST_RES_VAL).arg(cxStr, cyStr, fpsStr)));
unique_lock<mutex> ul(m);
if (cancel)
@ -683,7 +675,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
if (!obs_output_start(output)) {
QMetaObject::invokeMethod(this, "Failure",
Q_ARG(QString, QTStr(TEST_RES_FAIL)));
Q_ARG(QString,
QTStr(TEST_RES_FAIL)));
return false;
}
@ -692,8 +685,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
obs_output_stop(output);
cv.wait(ul);
int skipped = (int)video_output_get_skipped_frames(
obs_get_video());
int skipped =
(int)video_output_get_skipped_frames(obs_get_video());
if (force || skipped <= 10)
results.emplace_back(cx, cy, fps_num, fps_den);
@ -702,23 +695,38 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
if (wiz->specificFPSNum && wiz->specificFPSDen) {
count = 5;
if (!testRes(1.0, 0, 0, false)) return false;
if (!testRes(1.5, 0, 0, false)) return false;
if (!testRes(1.0 / 0.6, 0, 0, false)) return false;
if (!testRes(2.0, 0, 0, false)) return false;
if (!testRes(2.25, 0, 0, true)) return false;
if (!testRes(1.0, 0, 0, false))
return false;
if (!testRes(1.5, 0, 0, false))
return false;
if (!testRes(1.0 / 0.6, 0, 0, false))
return false;
if (!testRes(2.0, 0, 0, false))
return false;
if (!testRes(2.25, 0, 0, true))
return false;
} else {
count = 10;
if (!testRes(1.0, 60, 1, false)) return false;
if (!testRes(1.0, 30, 1, false)) return false;
if (!testRes(1.5, 60, 1, false)) return false;
if (!testRes(1.5, 30, 1, false)) return false;
if (!testRes(1.0 / 0.6, 60, 1, false)) return false;
if (!testRes(1.0 / 0.6, 30, 1, false)) return false;
if (!testRes(2.0, 60, 1, false)) return false;
if (!testRes(2.0, 30, 1, false)) return false;
if (!testRes(2.25, 60, 1, false)) return false;
if (!testRes(2.25, 30, 1, true)) return false;
if (!testRes(1.0, 60, 1, false))
return false;
if (!testRes(1.0, 30, 1, false))
return false;
if (!testRes(1.5, 60, 1, false))
return false;
if (!testRes(1.5, 30, 1, false))
return false;
if (!testRes(1.0 / 0.6, 60, 1, false))
return false;
if (!testRes(1.0 / 0.6, 30, 1, false))
return false;
if (!testRes(2.0, 60, 1, false))
return false;
if (!testRes(2.0, 30, 1, false))
return false;
if (!testRes(2.25, 60, 1, false))
return false;
if (!testRes(2.25, 30, 1, true))
return false;
}
/* -----------------------------------*/
@ -744,7 +752,7 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
wiz->idealFPSDen = result.fps_den;
long double fUpperBitrate = EstimateUpperBitrate(
result.cx, result.cy, result.fps_num, result.fps_den);
result.cx, result.cy, result.fps_num, result.fps_den);
int upperBitrate = int(floor(fUpperBitrate / 50.0l) * 50.0l);
@ -776,9 +784,8 @@ void AutoConfigTestPage::FindIdealHardwareResolution()
maxDataRate = 1280 * 720 * 30 + 1000;
}
auto testRes = [&] (long double div, int fps_num, int fps_den,
bool force)
{
auto testRes = [&](long double div, int fps_num, int fps_den,
bool force) {
if (results.size() >= 3)
return;
@ -805,7 +812,8 @@ void AutoConfigTestPage::FindIdealHardwareResolution()
* ratio, so increase the minimum bitrate estimate for them.
* NVENC currently is the exception because of the improvements
* its made to its quality in recent generations. */
if (!nvenc) minBitrate = minBitrate * 114 / 100;
if (!nvenc)
minBitrate = minBitrate * 114 / 100;
if (wiz->type == AutoConfig::Type::Recording)
force = true;
@ -919,9 +927,9 @@ void AutoConfigTestPage::TestRecordingEncoderThread()
#define ENCODER_TEXT(x) "Basic.Settings.Output.Simple.Encoder." x
#define ENCODER_SOFTWARE ENCODER_TEXT("Software")
#define ENCODER_NVENC ENCODER_TEXT("Hardware.NVENC")
#define ENCODER_QSV ENCODER_TEXT("Hardware.QSV")
#define ENCODER_AMD ENCODER_TEXT("Hardware.AMD")
#define ENCODER_NVENC ENCODER_TEXT("Hardware.NVENC")
#define ENCODER_QSV ENCODER_TEXT("Hardware.QSV")
#define ENCODER_AMD ENCODER_TEXT("Hardware.AMD")
#define QUALITY_SAME "Basic.Settings.Output.Simple.RecordingQuality.Stream"
#define QUALITY_HIGH "Basic.Settings.Output.Simple.RecordingQuality.Small"
@ -933,8 +941,7 @@ void AutoConfigTestPage::FinalizeResults()
QFormLayout *form = results;
auto encName = [] (AutoConfig::Encoder enc) -> QString
{
auto encName = [](AutoConfig::Encoder enc) -> QString {
switch (enc) {
case AutoConfig::Encoder::x264:
return QTStr(ENCODER_SOFTWARE);
@ -951,18 +958,16 @@ void AutoConfigTestPage::FinalizeResults()
return QTStr(ENCODER_SOFTWARE);
};
auto newLabel = [this] (const char *str) -> QLabel *
{
auto newLabel = [this](const char *str) -> QLabel * {
return new QLabel(QTStr(str), this);
};
if (wiz->type != AutoConfig::Type::Recording) {
const char *serverType = wiz->customServer
? "rtmp_custom"
: "rtmp_common";
const char *serverType = wiz->customServer ? "rtmp_custom"
: "rtmp_common";
OBSService service = obs_service_create(serverType,
"temp_service", nullptr, nullptr);
OBSService service = obs_service_create(
serverType, "temp_service", nullptr, nullptr);
obs_service_release(service);
OBSData service_settings = obs_data_create();
@ -971,44 +976,45 @@ void AutoConfigTestPage::FinalizeResults()
obs_data_release(vencoder_settings);
obs_data_set_int(vencoder_settings, "bitrate",
wiz->idealBitrate);
wiz->idealBitrate);
obs_data_set_string(service_settings, "service",
wiz->serviceName.c_str());
wiz->serviceName.c_str());
obs_service_update(service, service_settings);
obs_service_apply_encoder_settings(service,
vencoder_settings, nullptr);
obs_service_apply_encoder_settings(service, vencoder_settings,
nullptr);
wiz->idealBitrate = (int)obs_data_get_int(vencoder_settings,
"bitrate");
wiz->idealBitrate =
(int)obs_data_get_int(vencoder_settings, "bitrate");
if (!wiz->customServer)
form->addRow(
newLabel("Basic.AutoConfig.StreamPage.Service"),
new QLabel(wiz->serviceName.c_str(),
ui->finishPage));
ui->finishPage));
form->addRow(newLabel("Basic.AutoConfig.StreamPage.Server"),
new QLabel(wiz->serverName.c_str(), ui->finishPage));
new QLabel(wiz->serverName.c_str(),
ui->finishPage));
form->addRow(newLabel("Basic.Settings.Output.VideoBitrate"),
new QLabel(QString::number(wiz->idealBitrate),
ui->finishPage));
new QLabel(QString::number(wiz->idealBitrate),
ui->finishPage));
form->addRow(newLabel(TEST_RESULT_SE),
new QLabel(encName(wiz->streamingEncoder),
ui->finishPage));
new QLabel(encName(wiz->streamingEncoder),
ui->finishPage));
}
QString baseRes = QString("%1x%2").arg(
QString::number(wiz->baseResolutionCX),
QString::number(wiz->baseResolutionCY));
QString scaleRes = QString("%1x%2").arg(
QString::number(wiz->idealResolutionCX),
QString::number(wiz->idealResolutionCY));
QString baseRes =
QString("%1x%2").arg(QString::number(wiz->baseResolutionCX),
QString::number(wiz->baseResolutionCY));
QString scaleRes =
QString("%1x%2").arg(QString::number(wiz->idealResolutionCX),
QString::number(wiz->idealResolutionCY));
if (wiz->recordingEncoder != AutoConfig::Encoder::Stream ||
wiz->recordingQuality != AutoConfig::Quality::Stream)
form->addRow(newLabel(TEST_RESULT_RE),
new QLabel(encName(wiz->recordingEncoder),
ui->finishPage));
new QLabel(encName(wiz->recordingEncoder),
ui->finishPage));
QString recQuality;
@ -1022,21 +1028,20 @@ void AutoConfigTestPage::FinalizeResults()
}
form->addRow(newLabel("Basic.Settings.Output.Simple.RecordingQuality"),
new QLabel(recQuality, ui->finishPage));
new QLabel(recQuality, ui->finishPage));
long double fps =
(long double)wiz->idealFPSNum / (long double)wiz->idealFPSDen;
QString fpsStr = (wiz->idealFPSDen > 1)
? QString::number(fps, 'f', 2)
: QString::number(fps, 'g', 2);
QString fpsStr = (wiz->idealFPSDen > 1) ? QString::number(fps, 'f', 2)
: QString::number(fps, 'g', 2);
form->addRow(newLabel("Basic.Settings.Video.BaseResolution"),
new QLabel(baseRes, ui->finishPage));
new QLabel(baseRes, ui->finishPage));
form->addRow(newLabel("Basic.Settings.Video.ScaledResolution"),
new QLabel(scaleRes, ui->finishPage));
new QLabel(scaleRes, ui->finishPage));
form->addRow(newLabel("Basic.Settings.Video.FPS"),
new QLabel(fpsStr, ui->finishPage));
new QLabel(fpsStr, ui->finishPage));
}
#define STARTING_SEPARATOR \
@ -1103,8 +1108,7 @@ void AutoConfigTestPage::Progress(int percentage)
}
AutoConfigTestPage::AutoConfigTestPage(QWidget *parent)
: QWizardPage (parent),
ui (new Ui_AutoConfigTestPage)
: QWizardPage(parent), ui(new Ui_AutoConfigTestPage)
{
ui->setupUi(this);
setTitle(QTStr("Basic.AutoConfig.TestPage"));

View File

@ -20,10 +20,10 @@
struct QCef;
struct QCefCookieManager;
extern QCef *cef;
extern QCef *cef;
extern QCefCookieManager *panel_cookies;
#define wiz reinterpret_cast<AutoConfig*>(wizard())
#define wiz reinterpret_cast<AutoConfig *>(wizard())
/* ------------------------------------------------------------------------- */
@ -33,12 +33,12 @@ static OBSData OpenServiceSettings(std::string &type)
{
char serviceJsonPath[512];
int ret = GetProfilePath(serviceJsonPath, sizeof(serviceJsonPath),
SERVICE_PATH);
SERVICE_PATH);
if (ret <= 0)
return OBSData();
OBSData data = obs_data_create_from_json_file_safe(serviceJsonPath,
"bak");
OBSData data =
obs_data_create_from_json_file_safe(serviceJsonPath, "bak");
obs_data_release(data);
obs_data_set_default_string(data, "type", "rtmp_common");
@ -51,7 +51,7 @@ static OBSData OpenServiceSettings(std::string &type)
}
static void GetServiceInfo(std::string &type, std::string &service,
std::string &server, std::string &key)
std::string &server, std::string &key)
{
OBSData settings = OpenServiceSettings(type);
@ -63,8 +63,7 @@ static void GetServiceInfo(std::string &type, std::string &service,
/* ------------------------------------------------------------------------- */
AutoConfigStartPage::AutoConfigStartPage(QWidget *parent)
: QWizardPage (parent),
ui (new Ui_AutoConfigStartPage)
: QWizardPage(parent), ui(new Ui_AutoConfigStartPage)
{
ui->setupUi(this);
setTitle(QTStr("Basic.AutoConfig.StartPage"));
@ -93,16 +92,15 @@ void AutoConfigStartPage::on_prioritizeRecording_clicked()
/* ------------------------------------------------------------------------- */
#define RES_TEXT(x) "Basic.AutoConfig.VideoPage." x
#define RES_USE_CURRENT RES_TEXT("BaseResolution.UseCurrent")
#define RES_USE_DISPLAY RES_TEXT("BaseResolution.Display")
#define FPS_USE_CURRENT RES_TEXT("FPS.UseCurrent")
#define FPS_PREFER_HIGH_FPS RES_TEXT("FPS.PreferHighFPS")
#define FPS_PREFER_HIGH_RES RES_TEXT("FPS.PreferHighRes")
#define RES_TEXT(x) "Basic.AutoConfig.VideoPage." x
#define RES_USE_CURRENT RES_TEXT("BaseResolution.UseCurrent")
#define RES_USE_DISPLAY RES_TEXT("BaseResolution.Display")
#define FPS_USE_CURRENT RES_TEXT("FPS.UseCurrent")
#define FPS_PREFER_HIGH_FPS RES_TEXT("FPS.PreferHighFPS")
#define FPS_PREFER_HIGH_RES RES_TEXT("FPS.PreferHighRes")
AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
: QWizardPage (parent),
ui (new Ui_AutoConfigVideoPage)
: QWizardPage(parent), ui(new Ui_AutoConfigVideoPage)
{
ui->setupUi(this);
@ -115,16 +113,15 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
long double fpsVal =
(long double)ovi.fps_num / (long double)ovi.fps_den;
QString fpsStr = (ovi.fps_den > 1)
? QString::number(fpsVal, 'f', 2)
: QString::number(fpsVal, 'g', 2);
QString fpsStr = (ovi.fps_den > 1) ? QString::number(fpsVal, 'f', 2)
: QString::number(fpsVal, 'g', 2);
ui->fps->addItem(QTStr(FPS_PREFER_HIGH_FPS),
(int)AutoConfig::FPSType::PreferHighFPS);
(int)AutoConfig::FPSType::PreferHighFPS);
ui->fps->addItem(QTStr(FPS_PREFER_HIGH_RES),
(int)AutoConfig::FPSType::PreferHighRes);
(int)AutoConfig::FPSType::PreferHighRes);
ui->fps->addItem(QTStr(FPS_USE_CURRENT).arg(fpsStr),
(int)AutoConfig::FPSType::UseCurrent);
(int)AutoConfig::FPSType::UseCurrent);
ui->fps->addItem(QStringLiteral("30"), (int)AutoConfig::FPSType::fps30);
ui->fps->addItem(QStringLiteral("60"), (int)AutoConfig::FPSType::fps60);
ui->fps->setCurrentIndex(0);
@ -134,9 +131,9 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
int encRes = int(ovi.base_width << 16) | int(ovi.base_height);
ui->canvasRes->addItem(QTStr(RES_USE_CURRENT).arg(cxStr, cyStr),
(int)encRes);
(int)encRes);
QList<QScreen*> screens = QGuiApplication::screens();
QList<QScreen *> screens = QGuiApplication::screens();
for (int i = 0; i < screens.size(); i++) {
QScreen *screen = screens[i];
QSize as = screen->size();
@ -144,19 +141,17 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
encRes = int(as.width() << 16) | int(as.height());
QString str = QTStr(RES_USE_DISPLAY)
.arg(QString::number(i + 1),
QString::number(as.width()),
QString::number(as.height()));
.arg(QString::number(i + 1),
QString::number(as.width()),
QString::number(as.height()));
ui->canvasRes->addItem(str, encRes);
}
auto addRes = [&] (int cx, int cy)
{
auto addRes = [&](int cx, int cy) {
encRes = (cx << 16) | cy;
QString str = QString("%1x%2").arg(
QString::number(cx),
QString::number(cy));
QString str = QString("%1x%2").arg(QString::number(cx),
QString::number(cy));
ui->canvasRes->addItem(str, encRes);
};
@ -174,8 +169,8 @@ AutoConfigVideoPage::~AutoConfigVideoPage()
int AutoConfigVideoPage::nextId() const
{
return wiz->type == AutoConfig::Type::Recording
? AutoConfig::TestPage
: AutoConfig::StreamPage;
? AutoConfig::TestPage
: AutoConfig::StreamPage;
}
bool AutoConfigVideoPage::validatePage()
@ -223,12 +218,11 @@ bool AutoConfigVideoPage::validatePage()
enum class ListOpt : int {
ShowAll = 1,
Custom
Custom,
};
AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
: QWizardPage (parent),
ui (new Ui_AutoConfigStreamPage)
: QWizardPage(parent), ui(new Ui_AutoConfigStreamPage)
{
ui->setupUi(this);
ui->bitrateLabel->setVisible(false);
@ -255,29 +249,29 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
LoadServices(false);
connect(ui->service, SIGNAL(currentIndexChanged(int)),
this, SLOT(ServiceChanged()));
connect(ui->customServer, SIGNAL(textChanged(const QString &)),
this, SLOT(ServiceChanged()));
connect(ui->doBandwidthTest, SIGNAL(toggled(bool)),
this, SLOT(ServiceChanged()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(ServiceChanged()));
connect(ui->customServer, SIGNAL(textChanged(const QString &)), this,
SLOT(ServiceChanged()));
connect(ui->doBandwidthTest, SIGNAL(toggled(bool)), this,
SLOT(ServiceChanged()));
connect(ui->service, SIGNAL(currentIndexChanged(int)),
this, SLOT(UpdateServerList()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateServerList()));
connect(ui->service, SIGNAL(currentIndexChanged(int)),
this, SLOT(UpdateKeyLink()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateKeyLink()));
connect(ui->key, SIGNAL(textChanged(const QString &)),
this, SLOT(UpdateCompleted()));
connect(ui->regionUS, SIGNAL(toggled(bool)),
this, SLOT(UpdateCompleted()));
connect(ui->regionEU, SIGNAL(toggled(bool)),
this, SLOT(UpdateCompleted()));
connect(ui->regionAsia, SIGNAL(toggled(bool)),
this, SLOT(UpdateCompleted()));
connect(ui->regionOther, SIGNAL(toggled(bool)),
this, SLOT(UpdateCompleted()));
connect(ui->key, SIGNAL(textChanged(const QString &)), this,
SLOT(UpdateCompleted()));
connect(ui->regionUS, SIGNAL(toggled(bool)), this,
SLOT(UpdateCompleted()));
connect(ui->regionEU, SIGNAL(toggled(bool)), this,
SLOT(UpdateCompleted()));
connect(ui->regionAsia, SIGNAL(toggled(bool)), this,
SLOT(UpdateCompleted()));
connect(ui->regionOther, SIGNAL(toggled(bool)), this,
SLOT(UpdateCompleted()));
}
AutoConfigStreamPage::~AutoConfigStreamPage()
@ -307,17 +301,16 @@ bool AutoConfigStreamPage::validatePage()
wiz->customServer = IsCustom();
const char *serverType = wiz->customServer
? "rtmp_custom"
: "rtmp_common";
const char *serverType = wiz->customServer ? "rtmp_custom"
: "rtmp_common";
if (!wiz->customServer) {
obs_data_set_string(service_settings, "service",
QT_TO_UTF8(ui->service->currentText()));
QT_TO_UTF8(ui->service->currentText()));
}
OBSService service = obs_service_create(serverType, "temp_service",
service_settings, nullptr);
service_settings, nullptr);
obs_service_release(service);
int bitrate = 10000;
@ -365,9 +358,8 @@ bool AutoConfigStreamPage::validatePage()
if (wiz->service != AutoConfig::Service::Twitch && wiz->bandwidthTest) {
QMessageBox::StandardButton button;
#define WARNING_TEXT(x) QTStr("Basic.AutoConfig.StreamPage.StreamWarning." x)
button = OBSMessageBox::question(this,
WARNING_TEXT("Title"),
WARNING_TEXT("Text"));
button = OBSMessageBox::question(this, WARNING_TEXT("Title"),
WARNING_TEXT("Text"));
#undef WARNING_TEXT
if (button == QMessageBox::No)
@ -391,7 +383,7 @@ void AutoConfigStreamPage::on_show_clicked()
void AutoConfigStreamPage::OnOAuthStreamKeyConnected()
{
#ifdef BROWSER_AVAILABLE
OAuthStreamKey *a = reinterpret_cast<OAuthStreamKey*>(auth.get());
OAuthStreamKey *a = reinterpret_cast<OAuthStreamKey *>(auth.get());
if (a) {
bool validKey = !a->key().empty();
@ -440,9 +432,8 @@ void AutoConfigStreamPage::on_disconnectAccount_clicked()
{
QMessageBox::StandardButton button;
button = OBSMessageBox::question(this,
QTStr(DISCONNECT_COMFIRM_TITLE),
QTStr(DISCONNECT_COMFIRM_TEXT));
button = OBSMessageBox::question(this, QTStr(DISCONNECT_COMFIRM_TITLE),
QTStr(DISCONNECT_COMFIRM_TEXT));
if (button == QMessageBox::No) {
return;
@ -479,14 +470,13 @@ static inline bool is_auth_service(const std::string &service)
void AutoConfigStreamPage::ServiceChanged()
{
bool showMore =
ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
bool showMore = ui->service->currentData().toInt() ==
(int)ListOpt::ShowAll;
if (showMore)
return;
std::string service = QT_TO_UTF8(ui->service->currentText());
bool regionBased = service == "Twitch" ||
service == "Smashcast";
bool regionBased = service == "Twitch" || service == "Smashcast";
bool testBandwidth = ui->doBandwidthTest->isChecked();
bool custom = IsCustom();
@ -496,9 +486,8 @@ void AutoConfigStreamPage::ServiceChanged()
if (cef) {
if (lastService != service.c_str()) {
bool can_auth = is_auth_service(service);
int page = can_auth
? (int)Section::Connect
: (int)Section::StreamKey;
int page = can_auth ? (int)Section::Connect
: (int)Section::StreamKey;
ui->stackedWidget->setCurrentIndex(page);
ui->streamKeyWidget->setVisible(true);
@ -525,7 +514,7 @@ void AutoConfigStreamPage::ServiceChanged()
if (custom) {
ui->streamkeyPageLayout->insertRow(1, ui->serverLabel,
ui->serverStackedWidget);
ui->serverStackedWidget);
ui->region->setVisible(false);
ui->serverStackedWidget->setCurrentIndex(1);
@ -533,8 +522,8 @@ void AutoConfigStreamPage::ServiceChanged()
ui->serverLabel->setVisible(true);
} else {
if (!testBandwidth)
ui->streamkeyPageLayout->insertRow(2, ui->serverLabel,
ui->serverStackedWidget);
ui->streamkeyPageLayout->insertRow(
2, ui->serverLabel, ui->serverStackedWidget);
ui->region->setVisible(regionBased && testBandwidth);
ui->serverStackedWidget->setCurrentIndex(0);
@ -574,13 +563,15 @@ void AutoConfigStreamPage::UpdateKeyLink()
text += " <a href=\"https://";
text += "www.twitch.tv/broadcast/dashboard/streamkey";
text += "\">";
text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
text += QTStr(
"Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
text += "</a>";
} else if (serviceName == "YouTube / YouTube Gaming") {
text += " <a href=\"https://";
text += "www.youtube.com/live_dashboard";
text += "\">";
text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
text += QTStr(
"Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
text += "</a>";
isYoutube = true;
@ -632,9 +623,9 @@ void AutoConfigStreamPage::LoadServices(bool showAll)
QVariant((int)ListOpt::ShowAll));
}
ui->service->insertItem(0,
QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
QVariant((int)ListOpt::Custom));
ui->service->insertItem(
0, QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
QVariant((int)ListOpt::Custom));
if (!lastService.isEmpty()) {
int idx = ui->service->findText(lastService);
@ -650,8 +641,8 @@ void AutoConfigStreamPage::LoadServices(bool showAll)
void AutoConfigStreamPage::UpdateServerList()
{
QString serviceName = ui->service->currentText();
bool showMore =
ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
bool showMore = ui->service->currentData().toInt() ==
(int)ListOpt::ShowAll;
if (showMore) {
LoadServices(true);
@ -706,8 +697,7 @@ void AutoConfigStreamPage::UpdateCompleted()
/* ------------------------------------------------------------------------- */
AutoConfig::AutoConfig(QWidget *parent)
: QWizard(parent)
AutoConfig::AutoConfig(QWidget *parent) : QWizard(parent)
{
EnableThreadedMessageBoxes(true);
@ -718,7 +708,7 @@ AutoConfig::AutoConfig(QWidget *parent)
proc_handler_call(ph, "twitch_ingests_refresh", &cd);
calldata_free(&cd);
OBSBasic *main = reinterpret_cast<OBSBasic*>(parent);
OBSBasic *main = reinterpret_cast<OBSBasic *>(parent);
main->EnableOutputs(false);
installEventFilter(CreateShortcutFilter());
@ -805,14 +795,15 @@ AutoConfig::AutoConfig(QWidget *parent)
} else {
streamPage->ui->customServer->setText(server.c_str());
int idx = streamPage->ui->service->findData(
QVariant((int)ListOpt::Custom));
QVariant((int)ListOpt::Custom));
streamPage->ui->service->setCurrentIndex(idx);
}
if (!key.empty())
streamPage->ui->key->setText(key.c_str());
int bitrate = config_get_int(main->Config(), "SimpleOutput", "VBitrate");
int bitrate =
config_get_int(main->Config(), "SimpleOutput", "VBitrate");
streamPage->ui->bitrate->setValue(bitrate);
streamPage->ServiceChanged();
@ -825,13 +816,13 @@ AutoConfig::AutoConfig(QWidget *parent)
* bitrate ratio that if NVENC is available, it makes sense to
* just always prefer hardware encoding by default */
bool preferHardware = nvencAvailable ||
os_get_physical_cores() <= 4;
os_get_physical_cores() <= 4;
streamPage->ui->preferHardware->setChecked(preferHardware);
}
setOptions(0);
setButtonText(QWizard::FinishButton,
QTStr("Basic.AutoConfig.ApplySettings"));
QTStr("Basic.AutoConfig.ApplySettings"));
setButtonText(QWizard::BackButton, QTStr("Back"));
setButtonText(QWizard::NextButton, QTStr("Next"));
setButtonText(QWizard::CancelButton, QTStr("Cancel"));
@ -839,7 +830,7 @@ AutoConfig::AutoConfig(QWidget *parent)
AutoConfig::~AutoConfig()
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
main->EnableOutputs(true);
EnableThreadedMessageBoxes(false);
}
@ -879,13 +870,13 @@ bool AutoConfig::CanTestServer(const char *server)
if (strcmp(server, "Default") == 0) {
return true;
} else if (astrcmp_n(server, "US-West:", 8) == 0 ||
astrcmp_n(server, "US-East:", 8) == 0) {
astrcmp_n(server, "US-East:", 8) == 0) {
return regionUS;
} else if (astrcmp_n(server, "EU-", 3) == 0) {
return regionEU;
} else if (astrcmp_n(server, "South Korea:", 12) == 0 ||
astrcmp_n(server, "Asia:", 5) == 0 ||
astrcmp_n(server, "China:", 6) == 0) {
astrcmp_n(server, "Asia:", 5) == 0 ||
astrcmp_n(server, "China:", 6) == 0) {
return regionAsia;
} else if (regionOther) {
return true;
@ -924,14 +915,12 @@ inline const char *AutoConfig::GetEncoderId(Encoder enc)
void AutoConfig::SaveStreamSettings()
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
/* ---------------------------------- */
/* save service */
const char *service_id = customServer
? "rtmp_custom"
: "rtmp_common";
const char *service_id = customServer ? "rtmp_custom" : "rtmp_common";
obs_service_t *oldService = main->GetService();
OBSData hotkeyData = obs_hotkeys_save_service(oldService);
@ -945,8 +934,8 @@ void AutoConfig::SaveStreamSettings()
obs_data_set_string(settings, "server", server.c_str());
obs_data_set_string(settings, "key", key.c_str());
OBSService newService = obs_service_create(service_id,
"default_service", settings, hotkeyData);
OBSService newService = obs_service_create(
service_id, "default_service", settings, hotkeyData);
obs_service_release(newService);
if (!newService)
@ -962,26 +951,26 @@ void AutoConfig::SaveStreamSettings()
/* save stream settings */
config_set_int(main->Config(), "SimpleOutput", "VBitrate",
idealBitrate);
idealBitrate);
config_set_string(main->Config(), "SimpleOutput", "StreamEncoder",
GetEncoderId(streamingEncoder));
GetEncoderId(streamingEncoder));
config_remove_value(main->Config(), "SimpleOutput", "UseAdvanced");
}
void AutoConfig::SaveSettings()
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
if (recordingEncoder != Encoder::Stream)
config_set_string(main->Config(), "SimpleOutput", "RecEncoder",
GetEncoderId(recordingEncoder));
GetEncoderId(recordingEncoder));
const char *quality = recordingQuality == Quality::High
? "Small"
: "Stream";
const char *quality = recordingQuality == Quality::High ? "Small"
: "Stream";
config_set_string(main->Config(), "Output", "Mode", "Simple");
config_set_string(main->Config(), "SimpleOutput", "RecQuality", quality);
config_set_string(main->Config(), "SimpleOutput", "RecQuality",
quality);
config_set_int(main->Config(), "Video", "BaseCX", baseResolutionCX);
config_set_int(main->Config(), "Video", "BaseCY", baseResolutionCY);
config_set_int(main->Config(), "Video", "OutputCX", idealResolutionCX);
@ -990,7 +979,7 @@ void AutoConfig::SaveSettings()
if (fpsType != FPSType::UseCurrent) {
config_set_uint(main->Config(), "Video", "FPSType", 0);
config_set_string(main->Config(), "Video", "FPSCommon",
std::to_string(idealFPSNum).c_str());
std::to_string(idealFPSNum).c_str());
}
main->ResetVideo();

View File

@ -32,13 +32,13 @@ class AutoConfig : public QWizard {
enum class Type {
Invalid,
Streaming,
Recording
Recording,
};
enum class Service {
Twitch,
Smashcast,
Other
Other,
};
enum class Encoder {
@ -46,12 +46,12 @@ class AutoConfig : public QWizard {
NVENC,
QSV,
AMD,
Stream
Stream,
};
enum class Quality {
Stream,
High
High,
};
enum class FPSType : int {
@ -59,7 +59,7 @@ class AutoConfig : public QWizard {
PreferHighRes,
UseCurrent,
fps30,
fps60
fps60,
};
static inline const char *GetEncoderId(Encoder enc);
@ -119,7 +119,7 @@ public:
StartPage,
VideoPage,
StreamPage,
TestPage
TestPage,
};
};
@ -216,7 +216,7 @@ class AutoConfigTestPage : public QWizardPage {
BandwidthTest,
StreamEncoder,
RecordingEncoder,
Finished
Finished,
};
Stage stage = Stage::Starting;

View File

@ -36,45 +36,39 @@ using namespace std;
Q_DECLARE_METATYPE(OBSSource);
OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
: QDialog (parent),
ui (new Ui::OBSBasicFilters),
source (source_),
addSignal (obs_source_get_signal_handler(source),
"filter_add",
OBSBasicFilters::OBSSourceFilterAdded,
this),
removeSignal (obs_source_get_signal_handler(source),
"filter_remove",
OBSBasicFilters::OBSSourceFilterRemoved,
this),
reorderSignal (obs_source_get_signal_handler(source),
"reorder_filters",
OBSBasicFilters::OBSSourceReordered,
this),
removeSourceSignal (obs_source_get_signal_handler(source),
"remove",
OBSBasicFilters::SourceRemoved, this),
renameSourceSignal (obs_source_get_signal_handler(source),
"rename",
OBSBasicFilters::SourceRenamed, this),
noPreviewMargin (13)
: QDialog(parent),
ui(new Ui::OBSBasicFilters),
source(source_),
addSignal(obs_source_get_signal_handler(source), "filter_add",
OBSBasicFilters::OBSSourceFilterAdded, this),
removeSignal(obs_source_get_signal_handler(source), "filter_remove",
OBSBasicFilters::OBSSourceFilterRemoved, this),
reorderSignal(obs_source_get_signal_handler(source),
"reorder_filters", OBSBasicFilters::OBSSourceReordered,
this),
removeSourceSignal(obs_source_get_signal_handler(source), "remove",
OBSBasicFilters::SourceRemoved, this),
renameSourceSignal(obs_source_get_signal_handler(source), "rename",
OBSBasicFilters::SourceRenamed, this),
noPreviewMargin(13)
{
main = reinterpret_cast<OBSBasic*>(parent);
main = reinterpret_cast<OBSBasic *>(parent);
ui->setupUi(this);
UpdateFilters();
ui->asyncFilters->setItemDelegate(
new VisibilityItemDelegate(ui->asyncFilters));
new VisibilityItemDelegate(ui->asyncFilters));
ui->effectFilters->setItemDelegate(
new VisibilityItemDelegate(ui->effectFilters));
new VisibilityItemDelegate(ui->effectFilters));
const char *name = obs_source_get_name(source);
setWindowTitle(QTStr("Basic.Filters.Title").arg(QT_UTF8(name)));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
#ifndef QT_NO_SHORTCUT
ui->actionRemoveFilter->setShortcut(QApplication::translate("OBSBasicFilters", "Del", nullptr));
ui->actionRemoveFilter->setShortcut(
QApplication::translate("OBSBasicFilters", "Del", nullptr));
#endif // QT_NO_SHORTCUT
addAction(ui->actionRemoveFilter);
@ -84,33 +78,33 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
installEventFilter(CreateShortcutFilter());
connect(ui->asyncFilters->itemDelegate(),
SIGNAL(closeEditor(QWidget*,
QAbstractItemDelegate::EndEditHint)),
this,
SLOT(AsyncFilterNameEdited(QWidget*,
QAbstractItemDelegate::EndEditHint)));
SIGNAL(closeEditor(QWidget *,
QAbstractItemDelegate::EndEditHint)),
this,
SLOT(AsyncFilterNameEdited(
QWidget *, QAbstractItemDelegate::EndEditHint)));
connect(ui->effectFilters->itemDelegate(),
SIGNAL(closeEditor(QWidget*,
QAbstractItemDelegate::EndEditHint)),
this,
SLOT(EffectFilterNameEdited(QWidget*,
QAbstractItemDelegate::EndEditHint)));
SIGNAL(closeEditor(QWidget *,
QAbstractItemDelegate::EndEditHint)),
this,
SLOT(EffectFilterNameEdited(
QWidget *, QAbstractItemDelegate::EndEditHint)));
QPushButton *close = ui->buttonBox->button(QDialogButtonBox::Close);
connect(close, SIGNAL(clicked()), this, SLOT(close()));
close->setDefault(true);
ui->buttonBox->button(QDialogButtonBox::Reset)->setText(
QTStr("Defaults"));
ui->buttonBox->button(QDialogButtonBox::Reset)
->setText(QTStr("Defaults"));
connect(ui->buttonBox->button(QDialogButtonBox::Reset),
SIGNAL(clicked()), this, SLOT(ResetFilters()));
uint32_t caps = obs_source_get_output_flags(source);
bool audio = (caps & OBS_SOURCE_AUDIO) != 0;
bool audio = (caps & OBS_SOURCE_AUDIO) != 0;
bool audioOnly = (caps & OBS_SOURCE_VIDEO) == 0;
bool async = (caps & OBS_SOURCE_ASYNC) != 0;
bool async = (caps & OBS_SOURCE_ASYNC) != 0;
if (!async && !audio) {
ui->asyncWidget->setVisible(false);
@ -124,22 +118,22 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
if (audioOnly || (audio && !async))
ui->asyncLabel->setText(QTStr("Basic.Filters.AudioFilters"));
auto addDrawCallback = [this] ()
{
auto addDrawCallback = [this]() {
obs_display_add_draw_callback(ui->preview->GetDisplay(),
OBSBasicFilters::DrawPreview, this);
OBSBasicFilters::DrawPreview,
this);
};
enum obs_source_type type = obs_source_get_type(source);
bool drawable_type = type == OBS_SOURCE_TYPE_INPUT ||
type == OBS_SOURCE_TYPE_SCENE;
type == OBS_SOURCE_TYPE_SCENE;
if ((caps & OBS_SOURCE_VIDEO) != 0) {
ui->rightLayout->setContentsMargins(0, 0, 0, 0);
ui->preview->show();
if (drawable_type)
connect(ui->preview, &OBSQTDisplay::DisplayCreated,
addDrawCallback);
addDrawCallback);
} else {
ui->rightLayout->setContentsMargins(0, noPreviewMargin, 0, 0);
ui->rightContainerLayout->insertStretch(1);
@ -187,14 +181,14 @@ void OBSBasicFilters::UpdatePropertiesView(int row, bool async)
obs_data_t *settings = obs_source_get_settings(filter);
view = new OBSPropertiesView(settings, filter,
(PropertiesReloadCallback)obs_source_properties,
(PropertiesUpdateCallback)obs_source_update);
view = new OBSPropertiesView(
settings, filter,
(PropertiesReloadCallback)obs_source_properties,
(PropertiesUpdateCallback)obs_source_update);
updatePropertiesSignal.Connect(obs_source_get_signal_handler(filter),
"update_properties",
OBSBasicFilters::UpdateProperties,
this);
"update_properties",
OBSBasicFilters::UpdateProperties, this);
obs_data_release(settings);
@ -206,8 +200,8 @@ void OBSBasicFilters::UpdatePropertiesView(int row, bool async)
void OBSBasicFilters::UpdateProperties(void *data, calldata_t *)
{
QMetaObject::invokeMethod(static_cast<OBSBasicFilters*>(data)->view,
"ReloadProperties");
QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(data)->view,
"ReloadProperties");
}
void OBSBasicFilters::AddFilter(OBSSource filter)
@ -252,7 +246,7 @@ void OBSBasicFilters::RemoveFilter(OBSSource filter)
const char *filterId = obs_source_get_id(filter);
blog(LOG_INFO, "User removed filter '%s' (%s) from source '%s'",
filterName, filterId, sourceName);
filterName, filterId, sourceName);
main->SaveProject();
}
@ -265,8 +259,8 @@ struct FilterOrderInfo {
inline FilterOrderInfo(OBSBasicFilters *window_) : window(window_) {}
};
void OBSBasicFilters::ReorderFilter(QListWidget *list,
obs_source_t *filter, size_t idx)
void OBSBasicFilters::ReorderFilter(QListWidget *list, obs_source_t *filter,
size_t idx)
{
int count = list->count();
@ -280,10 +274,10 @@ void OBSBasicFilters::ReorderFilter(QListWidget *list,
bool sel = (list->currentRow() == i);
listItem = TakeListItem(list, i);
if (listItem) {
if (listItem) {
list->insertItem((int)idx, listItem);
SetupVisibilityItem(list,
listItem, filterItem);
SetupVisibilityItem(list, listItem,
filterItem);
if (sel)
list->setCurrentRow((int)idx);
@ -299,27 +293,28 @@ void OBSBasicFilters::ReorderFilters()
{
FilterOrderInfo info(this);
obs_source_enum_filters(source,
[] (obs_source_t*, obs_source_t *filter, void *p)
{
FilterOrderInfo *info =
reinterpret_cast<FilterOrderInfo*>(p);
uint32_t flags;
bool async;
obs_source_enum_filters(
source,
[](obs_source_t *, obs_source_t *filter, void *p) {
FilterOrderInfo *info =
reinterpret_cast<FilterOrderInfo *>(p);
uint32_t flags;
bool async;
flags = obs_source_get_output_flags(filter);
async = (flags & OBS_SOURCE_ASYNC) != 0;
flags = obs_source_get_output_flags(filter);
async = (flags & OBS_SOURCE_ASYNC) != 0;
if (async) {
info->window->ReorderFilter(
info->window->ui->asyncFilters,
filter, info->asyncIdx++);
} else {
info->window->ReorderFilter(
info->window->ui->effectFilters,
filter, info->effectIdx++);
}
}, &info);
if (async) {
info->window->ReorderFilter(
info->window->ui->asyncFilters, filter,
info->asyncIdx++);
} else {
info->window->ReorderFilter(
info->window->ui->effectFilters, filter,
info->effectIdx++);
}
},
&info);
}
void OBSBasicFilters::UpdateFilters()
@ -330,33 +325,34 @@ void OBSBasicFilters::UpdateFilters()
ClearListItems(ui->effectFilters);
ClearListItems(ui->asyncFilters);
obs_source_enum_filters(source,
[] (obs_source_t*, obs_source_t *filter, void *p)
{
OBSBasicFilters *window =
reinterpret_cast<OBSBasicFilters*>(p);
obs_source_enum_filters(
source,
[](obs_source_t *, obs_source_t *filter, void *p) {
OBSBasicFilters *window =
reinterpret_cast<OBSBasicFilters *>(p);
window->AddFilter(filter);
}, this);
window->AddFilter(filter);
},
this);
main->SaveProject();
}
static bool filter_compatible(bool async, uint32_t sourceFlags,
uint32_t filterFlags)
uint32_t filterFlags)
{
bool filterVideo = (filterFlags & OBS_SOURCE_VIDEO) != 0;
bool filterAsync = (filterFlags & OBS_SOURCE_ASYNC) != 0;
bool filterAudio = (filterFlags & OBS_SOURCE_AUDIO) != 0;
bool audio = (sourceFlags & OBS_SOURCE_AUDIO) != 0;
bool audioOnly = (sourceFlags & OBS_SOURCE_VIDEO) == 0;
bool audio = (sourceFlags & OBS_SOURCE_AUDIO) != 0;
bool audioOnly = (sourceFlags & OBS_SOURCE_VIDEO) == 0;
bool asyncSource = (sourceFlags & OBS_SOURCE_ASYNC) != 0;
if (async && ((audioOnly && filterVideo) || (!audio && !asyncSource)))
return false;
return (async && (filterAudio || filterAsync)) ||
(!async && !filterAudio && !filterAsync);
(!async && !filterAudio && !filterAsync);
}
QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
@ -372,7 +368,8 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
inline FilterInfo(const char *type_, const char *name_)
: type(type_), name(name_)
{}
{
}
};
vector<FilterInfo> types;
@ -396,17 +393,17 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
QMenu *popup = new QMenu(QTStr("Add"), this);
for (FilterInfo &type : types) {
uint32_t filterFlags = obs_get_source_output_flags(
type.type.c_str());
uint32_t filterFlags =
obs_get_source_output_flags(type.type.c_str());
if (!filter_compatible(async, sourceFlags, filterFlags))
continue;
QAction *popupItem = new QAction(QT_UTF8(type.name.c_str()),
this);
QAction *popupItem =
new QAction(QT_UTF8(type.name.c_str()), this);
popupItem->setData(QT_UTF8(type.type.c_str()));
connect(popupItem, SIGNAL(triggered(bool)),
this, SLOT(AddFilterFromAction()));
connect(popupItem, SIGNAL(triggered(bool)), this,
SLOT(AddFilterFromAction()));
popup->addAction(popupItem);
foundValues = true;
@ -426,40 +423,40 @@ void OBSBasicFilters::AddNewFilter(const char *id)
obs_source_t *existing_filter;
string name = obs_source_get_display_name(id);
bool success = NameDialog::AskForName(this,
QTStr("Basic.Filters.AddFilter.Title"),
QTStr("Basic.FIlters.AddFilter.Text"), name,
QT_UTF8(name.c_str()));
bool success = NameDialog::AskForName(
this, QTStr("Basic.Filters.AddFilter.Title"),
QTStr("Basic.FIlters.AddFilter.Text"), name,
QT_UTF8(name.c_str()));
if (!success)
return;
if (name.empty()) {
OBSMessageBox::warning(this,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
AddNewFilter(id);
return;
}
existing_filter = obs_source_get_filter_by_name(source,
name.c_str());
existing_filter =
obs_source_get_filter_by_name(source, name.c_str());
if (existing_filter) {
OBSMessageBox::warning(this,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
OBSMessageBox::warning(this, QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
obs_source_release(existing_filter);
AddNewFilter(id);
return;
}
obs_source_t *filter = obs_source_create(id, name.c_str(),
nullptr, nullptr);
obs_source_t *filter =
obs_source_create(id, name.c_str(), nullptr, nullptr);
if (filter) {
const char *sourceName = obs_source_get_name(source);
blog(LOG_INFO, "User added filter '%s' (%s) "
"to source '%s'",
name.c_str(), id, sourceName);
blog(LOG_INFO,
"User added filter '%s' (%s) "
"to source '%s'",
name.c_str(), id, sourceName);
obs_source_filter_add(source, filter);
obs_source_release(filter);
@ -469,7 +466,7 @@ void OBSBasicFilters::AddNewFilter(const char *id)
void OBSBasicFilters::AddFilterFromAction()
{
QAction *action = qobject_cast<QAction*>(sender());
QAction *action = qobject_cast<QAction *>(sender());
if (!action)
return;
@ -482,8 +479,8 @@ void OBSBasicFilters::closeEvent(QCloseEvent *event)
if (!event->isAccepted())
return;
obs_display_remove_draw_callback (ui->preview->GetDisplay(),
OBSBasicFilters::DrawPreview, this);
obs_display_remove_draw_callback(ui->preview->GetDisplay(),
OBSBasicFilters::DrawPreview, this);
main->SaveProject();
}
@ -492,26 +489,26 @@ void OBSBasicFilters::closeEvent(QCloseEvent *event)
void OBSBasicFilters::OBSSourceFilterAdded(void *param, calldata_t *data)
{
OBSBasicFilters *window = reinterpret_cast<OBSBasicFilters*>(param);
obs_source_t *filter = (obs_source_t*)calldata_ptr(data, "filter");
OBSBasicFilters *window = reinterpret_cast<OBSBasicFilters *>(param);
obs_source_t *filter = (obs_source_t *)calldata_ptr(data, "filter");
QMetaObject::invokeMethod(window, "AddFilter",
Q_ARG(OBSSource, OBSSource(filter)));
Q_ARG(OBSSource, OBSSource(filter)));
}
void OBSBasicFilters::OBSSourceFilterRemoved(void *param, calldata_t *data)
{
OBSBasicFilters *window = reinterpret_cast<OBSBasicFilters*>(param);
obs_source_t *filter = (obs_source_t*)calldata_ptr(data, "filter");
OBSBasicFilters *window = reinterpret_cast<OBSBasicFilters *>(param);
obs_source_t *filter = (obs_source_t *)calldata_ptr(data, "filter");
QMetaObject::invokeMethod(window, "RemoveFilter",
Q_ARG(OBSSource, OBSSource(filter)));
Q_ARG(OBSSource, OBSSource(filter)));
}
void OBSBasicFilters::OBSSourceReordered(void *param, calldata_t *data)
{
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicFilters*>(param),
"ReorderFilters");
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicFilters *>(param),
"ReorderFilters");
UNUSED_PARAMETER(data);
}
@ -520,8 +517,8 @@ void OBSBasicFilters::SourceRemoved(void *param, calldata_t *data)
{
UNUSED_PARAMETER(data);
QMetaObject::invokeMethod(static_cast<OBSBasicFilters*>(param),
"close");
QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(param),
"close");
}
void OBSBasicFilters::SourceRenamed(void *param, calldata_t *data)
@ -529,13 +526,13 @@ void OBSBasicFilters::SourceRenamed(void *param, calldata_t *data)
const char *name = calldata_string(data, "new_name");
QString title = QTStr("Basic.Filters.Title").arg(QT_UTF8(name));
QMetaObject::invokeMethod(static_cast<OBSBasicFilters*>(param),
"setWindowTitle", Q_ARG(QString, title));
QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(param),
"setWindowTitle", Q_ARG(QString, title));
}
void OBSBasicFilters::DrawPreview(void *data, uint32_t cx, uint32_t cy)
{
OBSBasicFilters *window = static_cast<OBSBasicFilters*>(data);
OBSBasicFilters *window = static_cast<OBSBasicFilters *>(data);
if (!window->source)
return;
@ -543,8 +540,8 @@ void OBSBasicFilters::DrawPreview(void *data, uint32_t cx, uint32_t cy)
uint32_t sourceCX = max(obs_source_get_width(window->source), 1u);
uint32_t sourceCY = max(obs_source_get_height(window->source), 1u);
int x, y;
int newCX, newCY;
int x, y;
int newCX, newCY;
float scale;
GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale);
@ -567,15 +564,15 @@ void OBSBasicFilters::DrawPreview(void *data, uint32_t cx, uint32_t cy)
static bool QueryRemove(QWidget *parent, obs_source_t *source)
{
const char *name = obs_source_get_name(source);
const char *name = obs_source_get_name(source);
QString text = QTStr("ConfirmRemove.Text");
text.replace("$1", QT_UTF8(name));
QMessageBox remove_source(parent);
remove_source.setText(text);
QAbstractButton *Yes = remove_source.addButton(QTStr("Yes"),
QMessageBox::YesRole);
QAbstractButton *Yes =
remove_source.addButton(QTStr("Yes"), QMessageBox::YesRole);
remove_source.addButton(QTStr("No"), QMessageBox::NoRole);
remove_source.setIcon(QMessageBox::Question);
remove_source.setWindowTitle(QTStr("ConfirmRemove.Title"));
@ -612,7 +609,7 @@ void OBSBasicFilters::on_moveAsyncFilterDown_clicked()
OBSSource filter = GetFilter(ui->asyncFilters->currentRow(), true);
if (filter)
obs_source_filter_set_order(source, filter,
OBS_ORDER_MOVE_DOWN);
OBS_ORDER_MOVE_DOWN);
}
void OBSBasicFilters::on_asyncFilters_GotFocus()
@ -654,7 +651,7 @@ void OBSBasicFilters::on_moveEffectFilterDown_clicked()
OBSSource filter = GetFilter(ui->effectFilters->currentRow(), false);
if (filter)
obs_source_filter_set_order(source, filter,
OBS_ORDER_MOVE_DOWN);
OBS_ORDER_MOVE_DOWN);
}
void OBSBasicFilters::on_effectFilters_GotFocus()
@ -704,11 +701,11 @@ void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async)
popup.addMenu(addMenu);
if (item) {
const char *renameSlot = async ?
SLOT(RenameAsyncFilter()) : SLOT(RenameEffectFilter());
const char *removeSlot = async ?
SLOT(on_removeAsyncFilter_clicked()) :
SLOT(on_removeEffectFilter_clicked());
const char *renameSlot = async ? SLOT(RenameAsyncFilter())
: SLOT(RenameEffectFilter());
const char *removeSlot =
async ? SLOT(on_removeAsyncFilter_clicked())
: SLOT(on_removeEffectFilter_clicked());
popup.addSeparator();
popup.addAction(QTStr("Rename"), this, renameSlot);
@ -721,9 +718,9 @@ void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async)
void OBSBasicFilters::EditItem(QListWidgetItem *item, bool async)
{
Qt::ItemFlags flags = item->flags();
OBSSource filter = item->data(Qt::UserRole).value<OBSSource>();
const char *name = obs_source_get_name(filter);
QListWidget *list = async ? ui->asyncFilters : ui->effectFilters;
OBSSource filter = item->data(Qt::UserRole).value<OBSSource>();
const char *name = obs_source_get_name(filter);
QListWidget *list = async ? ui->asyncFilters : ui->effectFilters;
item->setText(QT_UTF8(name));
item->setFlags(flags | Qt::ItemIsEditable);
@ -733,13 +730,13 @@ void OBSBasicFilters::EditItem(QListWidgetItem *item, bool async)
}
void OBSBasicFilters::on_asyncFilters_customContextMenuRequested(
const QPoint &pos)
const QPoint &pos)
{
CustomContextMenu(pos, true);
}
void OBSBasicFilters::on_effectFilters_customContextMenuRequested(
const QPoint &pos)
const QPoint &pos)
{
CustomContextMenu(pos, false);
}
@ -758,7 +755,7 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
{
QListWidgetItem *listItem = list->currentItem();
OBSSource filter = listItem->data(Qt::UserRole).value<OBSSource>();
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
QLineEdit *edit = qobject_cast<QLineEdit *>(editor);
string name = QT_TO_UTF8(edit->text().trimmed());
const char *prevName = obs_source_get_name(filter);
@ -766,28 +763,29 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
obs_source_t *foundFilter = nullptr;
if (!sameName)
foundFilter = obs_source_get_filter_by_name(source,
name.c_str());
foundFilter =
obs_source_get_filter_by_name(source, name.c_str());
if (foundFilter || name.empty() || sameName) {
listItem->setText(QT_UTF8(prevName));
if (foundFilter) {
OBSMessageBox::information(window(),
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
obs_source_release(foundFilter);
} else if (name.empty()) {
OBSMessageBox::information(window(),
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
}
} else {
const char *sourceName = obs_source_get_name(source);
blog(LOG_INFO, "User renamed filter '%s' on source '%s' to '%s'",
prevName, sourceName, name.c_str());
blog(LOG_INFO,
"User renamed filter '%s' on source '%s' to '%s'",
prevName, sourceName, name.c_str());
listItem->setText(QT_UTF8(name.c_str()));
obs_source_set_name(filter, name.c_str());
@ -797,15 +795,15 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
SetupVisibilityItem(list, listItem, filter);
}
void OBSBasicFilters::AsyncFilterNameEdited(QWidget *editor,
QAbstractItemDelegate::EndEditHint endHint)
void OBSBasicFilters::AsyncFilterNameEdited(
QWidget *editor, QAbstractItemDelegate::EndEditHint endHint)
{
FilterNameEdited(editor, ui->asyncFilters);
UNUSED_PARAMETER(endHint);
}
void OBSBasicFilters::EffectFilterNameEdited(QWidget *editor,
QAbstractItemDelegate::EndEditHint endHint)
void OBSBasicFilters::EffectFilterNameEdited(
QWidget *editor, QAbstractItemDelegate::EndEditHint endHint)
{
FilterNameEdited(editor, ui->effectFilters);
UNUSED_PARAMETER(endHint);

View File

@ -105,9 +105,9 @@ private slots:
void on_actionMoveDown_triggered();
void AsyncFilterNameEdited(QWidget *editor,
QAbstractItemDelegate::EndEditHint endHint);
QAbstractItemDelegate::EndEditHint endHint);
void EffectFilterNameEdited(QWidget *editor,
QAbstractItemDelegate::EndEditHint endHint);
QAbstractItemDelegate::EndEditHint endHint);
public:
OBSBasicFilters(QWidget *parent, OBSSource source_);

View File

@ -29,20 +29,20 @@
using namespace std;
OBSBasicInteraction::OBSBasicInteraction(QWidget *parent, OBSSource source_)
: QDialog (parent),
main (qobject_cast<OBSBasic*>(parent)),
ui (new Ui::OBSBasicInteraction),
source (source_),
removedSignal (obs_source_get_signal_handler(source), "remove",
OBSBasicInteraction::SourceRemoved, this),
renamedSignal (obs_source_get_signal_handler(source), "rename",
OBSBasicInteraction::SourceRenamed, this),
eventFilter (BuildEventFilter())
: QDialog(parent),
main(qobject_cast<OBSBasic *>(parent)),
ui(new Ui::OBSBasicInteraction),
source(source_),
removedSignal(obs_source_get_signal_handler(source), "remove",
OBSBasicInteraction::SourceRemoved, this),
renamedSignal(obs_source_get_signal_handler(source), "rename",
OBSBasicInteraction::SourceRenamed, this),
eventFilter(BuildEventFilter())
{
int cx = (int)config_get_int(App()->GlobalConfig(), "InteractionWindow",
"cx");
"cx");
int cy = (int)config_get_int(App()->GlobalConfig(), "InteractionWindow",
"cy");
"cy");
ui->setupUi(this);
@ -59,10 +59,10 @@ OBSBasicInteraction::OBSBasicInteraction(QWidget *parent, OBSSource source_)
const char *name = obs_source_get_name(source);
setWindowTitle(QTStr("Basic.InteractionWindow").arg(QT_UTF8(name)));
auto addDrawCallback = [this] ()
{
auto addDrawCallback = [this]() {
obs_display_add_draw_callback(ui->preview->GetDisplay(),
OBSBasicInteraction::DrawPreview, this);
OBSBasicInteraction::DrawPreview,
this);
};
connect(ui->preview, &OBSQTDisplay::DisplayCreated, addDrawCallback);
@ -77,34 +77,32 @@ OBSBasicInteraction::~OBSBasicInteraction()
OBSEventFilter *OBSBasicInteraction::BuildEventFilter()
{
return new OBSEventFilter(
[this](QObject *obj, QEvent *event)
{
return new OBSEventFilter([this](QObject *obj, QEvent *event) {
UNUSED_PARAMETER(obj);
switch(event->type()) {
switch (event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
return this->HandleMouseClickEvent(
static_cast<QMouseEvent *>(event));
static_cast<QMouseEvent *>(event));
case QEvent::MouseMove:
case QEvent::Enter:
case QEvent::Leave:
return this->HandleMouseMoveEvent(
static_cast<QMouseEvent *>(event));
static_cast<QMouseEvent *>(event));
case QEvent::Wheel:
return this->HandleMouseWheelEvent(
static_cast<QWheelEvent *>(event));
static_cast<QWheelEvent *>(event));
case QEvent::FocusIn:
case QEvent::FocusOut:
return this->HandleFocusEvent(
static_cast<QFocusEvent *>(event));
static_cast<QFocusEvent *>(event));
case QEvent::KeyPress:
case QEvent::KeyRelease:
return this->HandleKeyEvent(
static_cast<QKeyEvent *>(event));
static_cast<QKeyEvent *>(event));
default:
return false;
}
@ -113,8 +111,8 @@ OBSEventFilter *OBSBasicInteraction::BuildEventFilter()
void OBSBasicInteraction::SourceRemoved(void *data, calldata_t *params)
{
QMetaObject::invokeMethod(static_cast<OBSBasicInteraction*>(data),
"close");
QMetaObject::invokeMethod(static_cast<OBSBasicInteraction *>(data),
"close");
UNUSED_PARAMETER(params);
}
@ -124,13 +122,13 @@ void OBSBasicInteraction::SourceRenamed(void *data, calldata_t *params)
const char *name = calldata_string(params, "new_name");
QString title = QTStr("Basic.InteractionWindow").arg(QT_UTF8(name));
QMetaObject::invokeMethod(static_cast<OBSBasicProperties*>(data),
"setWindowTitle", Q_ARG(QString, title));
QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data),
"setWindowTitle", Q_ARG(QString, title));
}
void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy)
{
OBSBasicInteraction *window = static_cast<OBSBasicInteraction*>(data);
OBSBasicInteraction *window = static_cast<OBSBasicInteraction *>(data);
if (!window->source)
return;
@ -138,8 +136,8 @@ void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy)
uint32_t sourceCX = max(obs_source_get_width(window->source), 1u);
uint32_t sourceCY = max(obs_source_get_height(window->source), 1u);
int x, y;
int newCX, newCY;
int x, y;
int newCX, newCY;
float scale;
GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale);
@ -149,8 +147,7 @@ void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy)
gs_viewport_push();
gs_projection_push();
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY),
-100.0f, 100.0f);
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), -100.0f, 100.0f);
gs_set_viewport(x, y, newCX, newCY);
obs_source_video_render(window->source);
@ -165,15 +162,18 @@ void OBSBasicInteraction::closeEvent(QCloseEvent *event)
return;
config_set_int(App()->GlobalConfig(), "InteractionWindow", "cx",
width());
width());
config_set_int(App()->GlobalConfig(), "InteractionWindow", "cy",
height());
height());
obs_display_remove_draw_callback(ui->preview->GetDisplay(),
OBSBasicInteraction::DrawPreview, this);
OBSBasicInteraction::DrawPreview,
this);
}
static int TranslateQtKeyboardEventModifiers(QInputEvent *event, bool mouseEvent) {
static int TranslateQtKeyboardEventModifiers(QInputEvent *event,
bool mouseEvent)
{
int obsModifiers = INTERACT_NONE;
if (event->modifiers().testFlag(Qt::ShiftModifier))
@ -200,8 +200,7 @@ static int TranslateQtKeyboardEventModifiers(QInputEvent *event, bool mouseEvent
return obsModifiers;
}
static int TranslateQtMouseEventModifiers(
QMouseEvent *event)
static int TranslateQtMouseEventModifiers(QMouseEvent *event)
{
int modifiers = TranslateQtKeyboardEventModifiers(event, true);
@ -215,19 +214,19 @@ static int TranslateQtMouseEventModifiers(
return modifiers;
}
bool OBSBasicInteraction::GetSourceRelativeXY(
int mouseX, int mouseY, int &relX, int &relY)
bool OBSBasicInteraction::GetSourceRelativeXY(int mouseX, int mouseY, int &relX,
int &relY)
{
QSize size = GetPixelSize(ui->preview);
uint32_t sourceCX = max(obs_source_get_width(source), 1u);
uint32_t sourceCY = max(obs_source_get_height(source), 1u);
int x, y;
int x, y;
float scale;
GetScaleAndCenterPos(sourceCX, sourceCY, size.width(), size.height(),
x, y, scale);
GetScaleAndCenterPos(sourceCX, sourceCY, size.width(), size.height(), x,
y, scale);
if (x > 0) {
relX = int(float(mouseX - x) / scale);
@ -246,8 +245,7 @@ bool OBSBasicInteraction::GetSourceRelativeXY(
return true;
}
bool OBSBasicInteraction::HandleMouseClickEvent(
QMouseEvent *event)
bool OBSBasicInteraction::HandleMouseClickEvent(QMouseEvent *event)
{
bool mouseUp = event->type() == QEvent::MouseButtonRelease;
int clickCount = 1;
@ -271,8 +269,7 @@ bool OBSBasicInteraction::HandleMouseClickEvent(
button = MOUSE_RIGHT;
break;
default:
blog(LOG_WARNING, "unknown button type %d",
event->button());
blog(LOG_WARNING, "unknown button type %d", event->button());
return false;
}
@ -281,11 +278,11 @@ bool OBSBasicInteraction::HandleMouseClickEvent(
// clickCount = 2;
bool insideSource = GetSourceRelativeXY(event->x(), event->y(),
mouseEvent.x, mouseEvent.y);
mouseEvent.x, mouseEvent.y);
if (mouseUp || insideSource)
obs_source_send_mouse_click(source, &mouseEvent, button,
mouseUp, clickCount);
mouseUp, clickCount);
return true;
}
@ -299,7 +296,7 @@ bool OBSBasicInteraction::HandleMouseMoveEvent(QMouseEvent *event)
if (!mouseLeave) {
mouseEvent.modifiers = TranslateQtMouseEventModifiers(event);
mouseLeave = !GetSourceRelativeXY(event->x(), event->y(),
mouseEvent.x, mouseEvent.y);
mouseEvent.x, mouseEvent.y);
}
obs_source_send_mouse_move(source, &mouseEvent, mouseLeave);
@ -329,9 +326,9 @@ bool OBSBasicInteraction::HandleMouseWheelEvent(QWheelEvent *event)
}
if (GetSourceRelativeXY(event->x(), event->y(), mouseEvent.x,
mouseEvent.y))
mouseEvent.y))
obs_source_send_mouse_wheel(source, &mouseEvent, xDelta,
yDelta);
yDelta);
return true;
}

View File

@ -35,12 +35,12 @@ class OBSBasicInteraction : public QDialog {
Q_OBJECT
private:
OBSBasic *main;
OBSBasic *main;
std::unique_ptr<Ui::OBSBasicInteraction> ui;
OBSSource source;
OBSSignal removedSignal;
OBSSignal renamedSignal;
OBSSource source;
OBSSignal removedSignal;
OBSSignal renamedSignal;
std::unique_ptr<OBSEventFilter> eventFilter;
static void SourceRemoved(void *data, calldata_t *params);
@ -69,13 +69,10 @@ protected:
typedef std::function<bool(QObject *, QEvent *)> EventFilterFunc;
class OBSEventFilter : public QObject
{
class OBSEventFilter : public QObject {
Q_OBJECT
public:
OBSEventFilter(EventFilterFunc filter_)
: filter(filter_)
{}
OBSEventFilter(EventFilterFunc filter_) : filter(filter_) {}
protected:
bool eventFilter(QObject *obj, QEvent *event)

View File

@ -30,7 +30,7 @@
struct QCef;
struct QCefCookieManager;
extern QCef *cef;
extern QCef *cef;
extern QCefCookieManager *panel_cookies;
static std::string GenId()
@ -52,7 +52,8 @@ void CheckExistingCookieId()
if (config_has_user_value(main->Config(), "Panels", "CookieId"))
return;
config_set_string(main->Config(), "Panels", "CookieId", GenId().c_str());
config_set_string(main->Config(), "Panels", "CookieId",
GenId().c_str());
}
#ifdef BROWSER_AVAILABLE
@ -66,8 +67,8 @@ static void InitPanelCookieManager()
CheckExistingCookieId();
OBSBasic *main = OBSBasic::Get();
const char *cookie_id = config_get_string(main->Config(),
"Panels", "CookieId");
const char *cookie_id =
config_get_string(main->Config(), "Panels", "CookieId");
std::string sub_path;
sub_path += "obs_profile_cookies/";
@ -102,8 +103,8 @@ void DuplicateCurrentCookieProfile(ConfigFile &config)
#ifdef BROWSER_AVAILABLE
if (cef) {
OBSBasic *main = OBSBasic::Get();
std::string cookie_id = config_get_string(main->Config(),
"Panels", "CookieId");
std::string cookie_id =
config_get_string(main->Config(), "Panels", "CookieId");
std::string src_path;
src_path += "obs_profile_cookies/";
@ -136,9 +137,9 @@ void DuplicateCurrentCookieProfile(ConfigFile &config)
}
config_set_string(config, "Panels", "CookieId",
cookie_id.c_str());
cookie_id.c_str());
config_set_string(main->Config(), "Panels", "CookieId",
new_id.c_str());
new_id.c_str());
}
#else
UNUSED_PARAMETER(config);
@ -155,10 +156,9 @@ void OBSBasic::InitBrowserPanelSafeBlock()
return;
}
ExecThreadedWithoutBlocking(
[] {cef->wait_for_browser_init();},
QTStr("BrowserPanelInit.Title"),
QTStr("BrowserPanelInit.Text"));
ExecThreadedWithoutBlocking([] { cef->wait_for_browser_init(); },
QTStr("BrowserPanelInit.Title"),
QTStr("BrowserPanelInit.Text"));
InitPanelCookieManager();
#endif
}

View File

@ -11,34 +11,29 @@
using namespace std;
static const char *textExtensions[] = {
"txt", "log", nullptr
};
static const char *textExtensions[] = {"txt", "log", nullptr};
static const char *imageExtensions[] = {
"bmp", "tga", "png", "jpg", "jpeg", "gif", nullptr
};
static const char *imageExtensions[] = {"bmp", "tga", "png", "jpg",
"jpeg", "gif", nullptr};
static const char *htmlExtensions[] = {
"htm", "html", nullptr
};
static const char *htmlExtensions[] = {"htm", "html", nullptr};
static const char *mediaExtensions[] = {
"3ga", "669", "a52", "aac", "ac3", "adt", "adts", "aif", "aifc",
"aiff", "amb", "amr", "aob", "ape", "au", "awb", "caf", "dts",
"flac", "it", "kar", "m4a", "m4b", "m4p", "m5p", "mid", "mka",
"mlp", "mod", "mpa", "mp1", "mp2", "mp3", "mpc", "mpga", "mus",
"oga", "ogg", "oma", "opus", "qcp", "ra", "rmi", "s3m", "sid",
"spx", "tak", "thd", "tta", "voc", "vqf", "w64", "wav", "wma",
"wv", "xa", "xm", "3g2", "3gp", "3gp2", "3gpp", "amv", "asf", "avi",
"bik", "crf", "divx", "drc", "dv", "evo", "f4v", "flv", "gvi",
"gxf", "iso", "m1v", "m2v", "m2t", "m2ts", "m4v", "mkv", "mov",
"mp2", "mp2v", "mp4", "mp4v", "mpe", "mpeg", "mpeg1", "mpeg2",
"mpeg4", "mpg", "mpv2", "mts", "mtv", "mxf", "mxg", "nsv", "nuv",
"ogg", "ogm", "ogv", "ogx", "ps", "rec", "rm", "rmvb", "rpl", "thp",
"tod", "ts", "tts", "txd", "vob", "vro", "webm", "wm", "wmv", "wtv",
nullptr
};
"3ga", "669", "a52", "aac", "ac3", "adt", "adts", "aif",
"aifc", "aiff", "amb", "amr", "aob", "ape", "au", "awb",
"caf", "dts", "flac", "it", "kar", "m4a", "m4b", "m4p",
"m5p", "mid", "mka", "mlp", "mod", "mpa", "mp1", "mp2",
"mp3", "mpc", "mpga", "mus", "oga", "ogg", "oma", "opus",
"qcp", "ra", "rmi", "s3m", "sid", "spx", "tak", "thd",
"tta", "voc", "vqf", "w64", "wav", "wma", "wv", "xa",
"xm", "3g2", "3gp", "3gp2", "3gpp", "amv", "asf", "avi",
"bik", "crf", "divx", "drc", "dv", "evo", "f4v", "flv",
"gvi", "gxf", "iso", "m1v", "m2v", "m2t", "m2ts", "m4v",
"mkv", "mov", "mp2", "mp2v", "mp4", "mp4v", "mpe", "mpeg",
"mpeg1", "mpeg2", "mpeg4", "mpg", "mpv2", "mts", "mtv", "mxf",
"mxg", "nsv", "nuv", "ogg", "ogm", "ogv", "ogx", "ps",
"rec", "rm", "rmvb", "rpl", "thp", "tod", "ts", "tts",
"txd", "vob", "vro", "webm", "wm", "wmv", "wtv", nullptr};
static string GenerateSourceName(const char *base)
{
@ -50,7 +45,7 @@ static string GenerateSourceName(const char *base)
if (inc) {
name += " (";
name += to_string(inc+1);
name += to_string(inc + 1);
name += ")";
}
@ -62,7 +57,7 @@ static string GenerateSourceName(const char *base)
void OBSBasic::AddDropSource(const char *data, DropType image)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
obs_data_t *settings = obs_data_create();
obs_source_t *source = nullptr;
const char *type = nullptr;
@ -115,8 +110,8 @@ void OBSBasic::AddDropSource(const char *data, DropType image)
if (name.isEmpty())
name = obs_source_get_display_name(type);
source = obs_source_create(type,
GenerateSourceName(QT_TO_UTF8(name)).c_str(),
settings, nullptr);
GenerateSourceName(QT_TO_UTF8(name)).c_str(),
settings, nullptr);
if (source) {
OBSScene scene = main->GetCurrentScene();
obs_scene_add(scene, source);
@ -143,7 +138,7 @@ void OBSBasic::dragMoveEvent(QDragMoveEvent *event)
void OBSBasic::dropEvent(QDropEvent *event)
{
const QMimeData* mimeData = event->mimeData();
const QMimeData *mimeData = event->mimeData();
if (mimeData->hasUrls()) {
QList<QUrl> urls = mimeData->urls();
@ -162,20 +157,20 @@ void OBSBasic::dropEvent(QDropEvent *event)
const char **cmp;
#define CHECK_SUFFIX(extensions, type) \
cmp = extensions; \
while (*cmp) { \
if (strcmp(*cmp, suffix) == 0) { \
AddDropSource(QT_TO_UTF8(file), type); \
found = true; \
break; \
} \
\
cmp++; \
} \
\
if (found) \
continue;
#define CHECK_SUFFIX(extensions, type) \
cmp = extensions; \
while (*cmp) { \
if (strcmp(*cmp, suffix) == 0) { \
AddDropSource(QT_TO_UTF8(file), type); \
found = true; \
break; \
} \
\
cmp++; \
} \
\
if (found) \
continue;
CHECK_SUFFIX(textExtensions, DropType_Text);
CHECK_SUFFIX(htmlExtensions, DropType_Html);
@ -188,4 +183,3 @@ if (found) \
AddDropSource(QT_TO_UTF8(mimeData->text()), DropType_RawText);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -5,49 +5,49 @@
class OBSBasic;
struct BasicOutputHandler {
OBSOutput fileOutput;
OBSOutput streamOutput;
OBSOutput replayBuffer;
bool streamingActive = false;
bool recordingActive = false;
bool delayActive = false;
bool replayBufferActive = false;
OBSBasic *main;
OBSOutput fileOutput;
OBSOutput streamOutput;
OBSOutput replayBuffer;
bool streamingActive = false;
bool recordingActive = false;
bool delayActive = false;
bool replayBufferActive = false;
OBSBasic *main;
std::string outputType;
std::string lastError;
std::string outputType;
std::string lastError;
OBSSignal startRecording;
OBSSignal stopRecording;
OBSSignal startReplayBuffer;
OBSSignal stopReplayBuffer;
OBSSignal startStreaming;
OBSSignal stopStreaming;
OBSSignal streamDelayStarting;
OBSSignal streamStopping;
OBSSignal recordStopping;
OBSSignal replayBufferStopping;
OBSSignal startRecording;
OBSSignal stopRecording;
OBSSignal startReplayBuffer;
OBSSignal stopReplayBuffer;
OBSSignal startStreaming;
OBSSignal stopStreaming;
OBSSignal streamDelayStarting;
OBSSignal streamStopping;
OBSSignal recordStopping;
OBSSignal replayBufferStopping;
inline BasicOutputHandler(OBSBasic *main_) : main(main_) {}
virtual ~BasicOutputHandler() {};
virtual ~BasicOutputHandler(){};
virtual bool StartStreaming(obs_service_t *service) = 0;
virtual bool StartRecording() = 0;
virtual bool StartReplayBuffer() {return false;}
virtual bool StartReplayBuffer() { return false; }
virtual void StopStreaming(bool force = false) = 0;
virtual void StopRecording(bool force = false) = 0;
virtual void StopReplayBuffer(bool force = false) {(void)force;}
virtual void StopReplayBuffer(bool force = false) { (void)force; }
virtual bool StreamingActive() const = 0;
virtual bool RecordingActive() const = 0;
virtual bool ReplayBufferActive() const {return false;}
virtual bool ReplayBufferActive() const { return false; }
virtual void Update() = 0;
inline bool Active() const
{
return streamingActive || recordingActive || delayActive ||
replayBufferActive;
replayBufferActive;
}
};

View File

@ -30,13 +30,13 @@ extern void DuplicateCurrentCookieProfile(ConfigFile &config);
extern void CheckExistingCookieId();
extern void DeleteCookies();
void EnumProfiles(std::function<bool (const char *, const char *)> &&cb)
void EnumProfiles(std::function<bool(const char *, const char *)> &&cb)
{
char path[512];
os_glob_t *glob;
int ret = GetConfigPath(path, sizeof(path),
"obs-studio/basic/profiles/*");
"obs-studio/basic/profiles/*");
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get profiles config path");
return;
@ -54,8 +54,7 @@ void EnumProfiles(std::function<bool (const char *, const char *)> &&cb)
if (!glob->gl_pathv[i].directory)
continue;
if (strcmp(dirName, ".") == 0 ||
strcmp(dirName, "..") == 0)
if (strcmp(dirName, ".") == 0 || strcmp(dirName, "..") == 0)
continue;
std::string file = filePath;
@ -80,8 +79,7 @@ void EnumProfiles(std::function<bool (const char *, const char *)> &&cb)
static bool ProfileExists(const char *findName)
{
bool found = false;
auto func = [&](const char *name, const char*)
{
auto func = [&](const char *name, const char *) {
if (strcmp(name, findName) == 0) {
found = true;
return false;
@ -94,28 +92,28 @@ static bool ProfileExists(const char *findName)
}
static bool GetProfileName(QWidget *parent, std::string &name,
std::string &file, const char *title, const char *text,
const char *oldName = nullptr)
std::string &file, const char *title,
const char *text, const char *oldName = nullptr)
{
char path[512];
int ret;
for (;;) {
bool success = NameDialog::AskForName(parent, title, text,
name, QT_UTF8(oldName));
bool success = NameDialog::AskForName(parent, title, text, name,
QT_UTF8(oldName));
if (!success) {
return false;
}
if (name.empty()) {
OBSMessageBox::warning(parent,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
continue;
}
if (ProfileExists(name.c_str())) {
OBSMessageBox::warning(parent,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
continue;
}
break;
@ -123,7 +121,7 @@ static bool GetProfileName(QWidget *parent, std::string &name,
if (!GetFileSafeName(name.c_str(), file)) {
blog(LOG_WARNING, "Failed to create safe file name for '%s'",
name.c_str());
name.c_str());
return false;
}
@ -137,7 +135,7 @@ static bool GetProfileName(QWidget *parent, std::string &name,
if (!GetClosestUnusedFileName(file, nullptr)) {
blog(LOG_WARNING, "Failed to get closest file name for %s",
file.c_str());
file.c_str());
return false;
}
@ -170,13 +168,14 @@ static bool CopyProfile(const char *fromPartial, const char *to)
if (glob->gl_pathv[i].directory)
continue;
ret = snprintf(path, sizeof(path), "%s/%s",
to, strrchr(filePath, '/') + 1);
ret = snprintf(path, sizeof(path), "%s/%s", to,
strrchr(filePath, '/') + 1);
if (ret > 0) {
if (os_copyfile(filePath, path) != 0) {
blog(LOG_WARNING, "CopyProfile: Failed to "
"copy file %s to %s",
filePath, path);
blog(LOG_WARNING,
"CopyProfile: Failed to "
"copy file %s to %s",
filePath, path);
}
}
}
@ -187,7 +186,7 @@ static bool CopyProfile(const char *fromPartial, const char *to)
}
bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
const char *init_text, bool rename)
const char *init_text, bool rename)
{
std::string newName;
std::string newDir;
@ -197,12 +196,12 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
if (!GetProfileName(this, newName, newDir, title, text, init_text))
return false;
std::string curDir = config_get_string(App()->GlobalConfig(),
"Basic", "ProfileDir");
std::string curDir =
config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir");
char baseDir[512];
int ret = GetConfigPath(baseDir, sizeof(baseDir),
"obs-studio/basic/profiles/");
"obs-studio/basic/profiles/");
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get profiles config path");
return false;
@ -213,7 +212,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
if (os_mkdir(newPath.c_str()) < 0) {
blog(LOG_WARNING, "Failed to create profile directory '%s'",
newDir.c_str());
newDir.c_str());
return false;
}
@ -224,14 +223,14 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
if (config.Open(newPath.c_str(), CONFIG_OPEN_ALWAYS) != 0) {
blog(LOG_ERROR, "Failed to open new config file '%s'",
newDir.c_str());
newDir.c_str());
return false;
}
config_set_string(App()->GlobalConfig(), "Basic", "Profile",
newName.c_str());
newName.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir",
newDir.c_str());
newDir.c_str());
Auth::Save();
if (create_new) {
@ -253,7 +252,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
ResetProfileData();
blog(LOG_INFO, "Created profile '%s' (%s, %s)", newName.c_str(),
create_new ? "clean" : "duplicate", newDir.c_str());
create_new ? "clean" : "duplicate", newDir.c_str());
blog(LOG_INFO, "------------------------------------------------");
config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
@ -280,14 +279,14 @@ void OBSBasic::DeleteProfile(const char *profileName, const char *profileDir)
ret = snprintf(profilePath, 512, "%s/%s/*", basePath, profileDir);
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get path for profile dir '%s'",
profileDir);
profileDir);
return;
}
os_glob_t *glob;
if (os_glob(profilePath, 0, &glob) != 0) {
blog(LOG_WARNING, "Failed to glob profile dir '%s'",
profileDir);
profileDir);
return;
}
@ -305,21 +304,20 @@ void OBSBasic::DeleteProfile(const char *profileName, const char *profileDir)
ret = snprintf(profilePath, 512, "%s/%s", basePath, profileDir);
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get path for profile dir '%s'",
profileDir);
profileDir);
return;
}
os_rmdir(profilePath);
blog(LOG_INFO, "------------------------------------------------");
blog(LOG_INFO, "Removed profile '%s' (%s)",
profileName, profileDir);
blog(LOG_INFO, "Removed profile '%s' (%s)", profileName, profileDir);
blog(LOG_INFO, "------------------------------------------------");
}
void OBSBasic::RefreshProfiles()
{
QList<QAction*> menuActions = ui->profileMenu->actions();
QList<QAction *> menuActions = ui->profileMenu->actions();
int count = 0;
for (int i = 0; i < menuActions.count(); i++) {
@ -328,17 +326,16 @@ void OBSBasic::RefreshProfiles()
delete menuActions[i];
}
const char *curName = config_get_string(App()->GlobalConfig(),
"Basic", "Profile");
const char *curName =
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
auto addProfile = [&](const char *name, const char *path)
{
auto addProfile = [&](const char *name, const char *path) {
std::string file = strrchr(path, '/') + 1;
QAction *action = new QAction(QT_UTF8(name), this);
action->setProperty("file_name", QT_UTF8(path));
connect(action, &QAction::triggered,
this, &OBSBasic::ChangeProfile);
connect(action, &QAction::triggered, this,
&OBSBasic::ChangeProfile);
action->setCheckable(true);
action->setChecked(strcmp(name, curName) == 0);
@ -364,15 +361,15 @@ void OBSBasic::ResetProfileData()
/* load audio monitoring */
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
const char *device_name = config_get_string(basicConfig, "Audio",
"MonitoringDeviceName");
const char *device_id = config_get_string(basicConfig, "Audio",
"MonitoringDeviceId");
const char *device_name =
config_get_string(basicConfig, "Audio", "MonitoringDeviceName");
const char *device_id =
config_get_string(basicConfig, "Audio", "MonitoringDeviceId");
obs_set_audio_monitoring_device(device_name, device_id);
blog(LOG_INFO, "Audio monitoring device:\n\tname: %s\n\tid: %s",
device_name, device_id);
device_name, device_id);
#endif
}
@ -388,14 +385,15 @@ void OBSBasic::on_actionDupProfile_triggered()
void OBSBasic::on_actionRenameProfile_triggered()
{
std::string curDir = config_get_string(App()->GlobalConfig(),
"Basic", "ProfileDir");
std::string curName = config_get_string(App()->GlobalConfig(),
"Basic", "Profile");
std::string curDir =
config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir");
std::string curName =
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
/* Duplicate and delete in case there are any issues in the process */
bool success = AddProfile(false, Str("RenameProfile.Title"),
Str("AddProfile.Text"), curName.c_str(), true);
Str("AddProfile.Text"), curName.c_str(),
true);
if (success) {
DeleteProfile(curName.c_str(), curDir.c_str());
RefreshProfiles();
@ -413,13 +411,12 @@ void OBSBasic::on_actionRemoveProfile_triggered()
std::string newPath;
ConfigFile config;
std::string oldDir = config_get_string(App()->GlobalConfig(),
"Basic", "ProfileDir");
std::string oldName = config_get_string(App()->GlobalConfig(),
"Basic", "Profile");
std::string oldDir =
config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir");
std::string oldName =
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
auto cb = [&](const char *name, const char *filePath)
{
auto cb = [&](const char *name, const char *filePath) {
if (strcmp(oldName.c_str(), name) != 0) {
newName = name;
newPath = filePath;
@ -438,8 +435,8 @@ void OBSBasic::on_actionRemoveProfile_triggered()
QString text = QTStr("ConfirmRemove.Text");
text.replace("$1", QT_UTF8(oldName.c_str()));
QMessageBox::StandardButton button = OBSMessageBox::question(this,
QTStr("ConfirmRemove.Title"), text);
QMessageBox::StandardButton button = OBSMessageBox::question(
this, QTStr("ConfirmRemove.Title"), text);
if (button == QMessageBox::No)
return;
@ -448,7 +445,7 @@ void OBSBasic::on_actionRemoveProfile_triggered()
if (config.Open(newPath.c_str(), CONFIG_OPEN_ALWAYS) != 0) {
blog(LOG_ERROR, "ChangeProfile: Failed to load file '%s'",
newPath.c_str());
newPath.c_str());
return;
}
@ -457,9 +454,8 @@ void OBSBasic::on_actionRemoveProfile_triggered()
const char *newDir = strrchr(newPath.c_str(), '/') + 1;
config_set_string(App()->GlobalConfig(), "Basic", "Profile",
newName.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir",
newDir);
newName.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir);
Auth::Save();
auth.reset();
@ -474,8 +470,8 @@ void OBSBasic::on_actionRemoveProfile_triggered()
RefreshProfiles();
config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
blog(LOG_INFO, "Switched to profile '%s' (%s)",
newName.c_str(), newDir);
blog(LOG_INFO, "Switched to profile '%s' (%s)", newName.c_str(),
newDir);
blog(LOG_INFO, "------------------------------------------------");
UpdateTitleBar();
@ -501,11 +497,8 @@ void OBSBasic::on_actionImportProfile_triggered()
}
QString dir = QFileDialog::getExistingDirectory(
this,
QTStr("Basic.MainMenu.Profile.Import"),
home,
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
this, QTStr("Basic.MainMenu.Profile.Import"), home,
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isEmpty() && !dir.isNull()) {
QString inputPath = QString::fromUtf8(path);
@ -517,18 +510,18 @@ void OBSBasic::on_actionImportProfile_triggered()
if (!folder.exists()) {
folder.mkpath(profileDir);
QFile::copy(dir + "/basic.ini",
profileDir + "/basic.ini");
profileDir + "/basic.ini");
QFile::copy(dir + "/service.json",
profileDir + "/service.json");
profileDir + "/service.json");
QFile::copy(dir + "/streamEncoder.json",
profileDir + "/streamEncoder.json");
profileDir + "/streamEncoder.json");
QFile::copy(dir + "/recordEncoder.json",
profileDir + "/recordEncoder.json");
profileDir + "/recordEncoder.json");
RefreshProfiles();
} else {
OBSMessageBox::warning(this,
QTStr("Basic.MainMenu.Profile.Import"),
QTStr("Basic.MainMenu.Profile.Exists"));
OBSMessageBox::warning(
this, QTStr("Basic.MainMenu.Profile.Import"),
QTStr("Basic.MainMenu.Profile.Exists"));
}
}
}
@ -539,9 +532,8 @@ void OBSBasic::on_actionExportProfile_triggered()
QString home = QDir::homePath();
QString currentProfile =
QString::fromUtf8(config_get_string(App()->GlobalConfig(),
"Basic", "ProfileDir"));
QString currentProfile = QString::fromUtf8(config_get_string(
App()->GlobalConfig(), "Basic", "ProfileDir"));
int ret = GetConfigPath(path, 512, "obs-studio/basic/profiles/");
if (ret <= 0) {
@ -550,11 +542,8 @@ void OBSBasic::on_actionExportProfile_triggered()
}
QString dir = QFileDialog::getExistingDirectory(
this,
QTStr("Basic.MainMenu.Profile.Export"),
home,
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
this, QTStr("Basic.MainMenu.Profile.Export"), home,
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isEmpty() && !dir.isNull()) {
QString outputDir = dir + "/" + currentProfile;
@ -571,26 +560,28 @@ void OBSBasic::on_actionExportProfile_triggered()
QFile::remove(outputDir + "/service.json");
if (QFile::exists(outputDir + "/streamEncoder.json"))
QFile::remove(outputDir + "/streamEncoder.json");
QFile::remove(outputDir +
"/streamEncoder.json");
if (QFile::exists(outputDir + "/recordEncoder.json"))
QFile::remove(outputDir + "/recordEncoder.json");
QFile::remove(outputDir +
"/recordEncoder.json");
}
QFile::copy(inputPath + currentProfile + "/basic.ini",
outputDir + "/basic.ini");
outputDir + "/basic.ini");
QFile::copy(inputPath + currentProfile + "/service.json",
outputDir + "/service.json");
outputDir + "/service.json");
QFile::copy(inputPath + currentProfile + "/streamEncoder.json",
outputDir + "/streamEncoder.json");
outputDir + "/streamEncoder.json");
QFile::copy(inputPath + currentProfile + "/recordEncoder.json",
outputDir + "/recordEncoder.json");
outputDir + "/recordEncoder.json");
}
}
void OBSBasic::ChangeProfile()
{
QAction *action = reinterpret_cast<QAction*>(sender());
QAction *action = reinterpret_cast<QAction *>(sender());
ConfigFile config;
std::string path;
@ -601,8 +592,8 @@ void OBSBasic::ChangeProfile()
if (path.empty())
return;
const char *oldName = config_get_string(App()->GlobalConfig(),
"Basic", "Profile");
const char *oldName =
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
if (action->text().compare(QT_UTF8(oldName)) == 0) {
action->setChecked(true);
return;
@ -613,7 +604,7 @@ void OBSBasic::ChangeProfile()
if (config.Open(path.c_str(), CONFIG_OPEN_ALWAYS) != 0) {
blog(LOG_ERROR, "ChangeProfile: Failed to load file '%s'",
path.c_str());
path.c_str());
return;
}
@ -623,8 +614,7 @@ void OBSBasic::ChangeProfile()
const char *newDir = strrchr(path.c_str(), '/') + 1;
config_set_string(App()->GlobalConfig(), "Basic", "Profile", newName);
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir",
newDir);
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir);
Auth::Save();
auth.reset();
@ -642,8 +632,7 @@ void OBSBasic::ChangeProfile()
CheckForSimpleModeX264Fallback();
blog(LOG_INFO, "Switched to profile '%s' (%s)",
newName, newDir);
blog(LOG_INFO, "Switched to profile '%s' (%s)", newName, newDir);
blog(LOG_INFO, "------------------------------------------------");
if (api)
@ -652,10 +641,10 @@ void OBSBasic::ChangeProfile()
void OBSBasic::CheckForSimpleModeX264Fallback()
{
const char *curStreamEncoder = config_get_string(basicConfig,
"SimpleOutput", "StreamEncoder");
const char *curRecEncoder = config_get_string(basicConfig,
"SimpleOutput", "RecEncoder");
const char *curStreamEncoder =
config_get_string(basicConfig, "SimpleOutput", "StreamEncoder");
const char *curRecEncoder =
config_get_string(basicConfig, "SimpleOutput", "RecEncoder");
bool qsv_supported = false;
bool amd_supported = false;
bool nve_supported = false;
@ -672,8 +661,7 @@ void OBSBasic::CheckForSimpleModeX264Fallback()
nve_supported = true;
}
auto CheckEncoder = [&] (const char *&name)
{
auto CheckEncoder = [&](const char *&name) {
if (strcmp(name, SIMPLE_ENCODER_QSV) == 0) {
if (!qsv_supported) {
changed = true;
@ -698,13 +686,11 @@ void OBSBasic::CheckForSimpleModeX264Fallback()
};
if (!CheckEncoder(curStreamEncoder))
config_set_string(basicConfig,
"SimpleOutput", "StreamEncoder",
curStreamEncoder);
config_set_string(basicConfig, "SimpleOutput", "StreamEncoder",
curStreamEncoder);
if (!CheckEncoder(curRecEncoder))
config_set_string(basicConfig,
"SimpleOutput", "RecEncoder",
curRecEncoder);
config_set_string(basicConfig, "SimpleOutput", "RecEncoder",
curRecEncoder);
if (changed)
config_save_safe(basicConfig, "tmp", nullptr);
}

View File

@ -28,16 +28,16 @@
using namespace std;
void EnumSceneCollections(std::function<bool (const char *, const char *)> &&cb)
void EnumSceneCollections(std::function<bool(const char *, const char *)> &&cb)
{
char path[512];
os_glob_t *glob;
int ret = GetConfigPath(path, sizeof(path),
"obs-studio/basic/scenes/*.json");
"obs-studio/basic/scenes/*.json");
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get config path for scene "
"collections");
"collections");
return;
}
@ -52,8 +52,8 @@ void EnumSceneCollections(std::function<bool (const char *, const char *)> &&cb)
if (glob->gl_pathv[i].directory)
continue;
obs_data_t *data = obs_data_create_from_json_file_safe(filePath,
"bak");
obs_data_t *data =
obs_data_create_from_json_file_safe(filePath, "bak");
std::string name = obs_data_get_string(data, "name");
/* if no name found, use the file name as the name
@ -75,8 +75,7 @@ void EnumSceneCollections(std::function<bool (const char *, const char *)> &&cb)
static bool SceneCollectionExists(const char *findName)
{
bool found = false;
auto func = [&](const char *name, const char*)
{
auto func = [&](const char *name, const char *) {
if (strcmp(name, findName) == 0) {
found = true;
return false;
@ -90,7 +89,8 @@ static bool SceneCollectionExists(const char *findName)
}
static bool GetSceneCollectionName(QWidget *parent, std::string &name,
std::string &file, const char *oldName = nullptr)
std::string &file,
const char *oldName = nullptr)
{
bool rename = oldName != nullptr;
const char *title;
@ -101,28 +101,28 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name,
if (rename) {
title = Str("Basic.Main.RenameSceneCollection.Title");
text = Str("Basic.Main.AddSceneCollection.Text");
text = Str("Basic.Main.AddSceneCollection.Text");
} else {
title = Str("Basic.Main.AddSceneCollection.Title");
text = Str("Basic.Main.AddSceneCollection.Text");
text = Str("Basic.Main.AddSceneCollection.Text");
}
for (;;) {
bool success = NameDialog::AskForName(parent, title, text,
name, QT_UTF8(oldName));
bool success = NameDialog::AskForName(parent, title, text, name,
QT_UTF8(oldName));
if (!success) {
return false;
}
if (name.empty()) {
OBSMessageBox::warning(parent,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
continue;
}
if (SceneCollectionExists(name.c_str())) {
OBSMessageBox::warning(parent,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
continue;
}
break;
@ -130,7 +130,7 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name,
if (!GetFileSafeName(name.c_str(), file)) {
blog(LOG_WARNING, "Failed to create safe file name for '%s'",
name.c_str());
name.c_str());
return false;
}
@ -145,7 +145,7 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name,
if (!GetClosestUnusedFileName(file, "json")) {
blog(LOG_WARNING, "Failed to get closest file name for %s",
file.c_str());
file.c_str());
return false;
}
@ -171,9 +171,9 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname)
SaveProjectNow();
config_set_string(App()->GlobalConfig(), "Basic", "SceneCollection",
name.c_str());
name.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "SceneCollectionFile",
file.c_str());
file.c_str());
if (create_new) {
CreateDefaultScene(false);
}
@ -181,8 +181,7 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname)
RefreshSceneCollections();
blog(LOG_INFO, "Added scene collection '%s' (%s, %s.json)",
name.c_str(), create_new ? "clean" : "duplicate",
file.c_str());
name.c_str(), create_new ? "clean" : "duplicate", file.c_str());
blog(LOG_INFO, "------------------------------------------------");
UpdateTitleBar();
@ -197,7 +196,7 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname)
void OBSBasic::RefreshSceneCollections()
{
QList<QAction*> menuActions = ui->sceneCollectionMenu->actions();
QList<QAction *> menuActions = ui->sceneCollectionMenu->actions();
int count = 0;
for (int i = 0; i < menuActions.count(); i++) {
@ -206,18 +205,17 @@ void OBSBasic::RefreshSceneCollections()
delete menuActions[i];
}
const char *cur_name = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
const char *cur_name = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
auto addCollection = [&](const char *name, const char *path)
{
auto addCollection = [&](const char *name, const char *path) {
std::string file = strrchr(path, '/') + 1;
file.erase(file.size() - 5, 5);
QAction *action = new QAction(QT_UTF8(name), this);
action->setProperty("file_name", QT_UTF8(path));
connect(action, &QAction::triggered,
this, &OBSBasic::ChangeSceneCollection);
connect(action, &QAction::triggered, this,
&OBSBasic::ChangeSceneCollection);
action->setCheckable(true);
action->setChecked(strcmp(name, cur_name) == 0);
@ -243,7 +241,7 @@ void OBSBasic::RefreshSceneCollections()
ui->actionRemoveSceneCollection->setEnabled(count > 1);
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
main->ui->actionPasteFilters->setEnabled(false);
main->ui->actionPasteRef->setEnabled(false);
@ -265,19 +263,19 @@ void OBSBasic::on_actionRenameSceneCollection_triggered()
std::string name;
std::string file;
std::string oldFile = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile");
const char *oldName = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
std::string oldFile = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile");
const char *oldName = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
bool success = GetSceneCollectionName(this, name, file, oldName);
if (!success)
return;
config_set_string(App()->GlobalConfig(), "Basic", "SceneCollection",
name.c_str());
name.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "SceneCollectionFile",
file.c_str());
file.c_str());
SaveProjectNow();
char path[512];
@ -295,7 +293,7 @@ void OBSBasic::on_actionRenameSceneCollection_triggered()
blog(LOG_INFO, "------------------------------------------------");
blog(LOG_INFO, "Renamed scene collection to '%s' (%s.json)",
name.c_str(), file.c_str());
name.c_str(), file.c_str());
blog(LOG_INFO, "------------------------------------------------");
UpdateTitleBar();
@ -312,13 +310,12 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
std::string newName;
std::string newPath;
std::string oldFile = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile");
std::string oldName = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
std::string oldFile = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile");
std::string oldName = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
auto cb = [&](const char *name, const char *filePath)
{
auto cb = [&](const char *name, const char *filePath) {
if (strcmp(oldName.c_str(), name) != 0) {
newName = name;
newPath = filePath;
@ -337,8 +334,8 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
QString text = QTStr("ConfirmRemove.Text");
text.replace("$1", QT_UTF8(oldName.c_str()));
QMessageBox::StandardButton button = OBSMessageBox::question(this,
QTStr("ConfirmRemove.Title"), text);
QMessageBox::StandardButton button = OBSMessageBox::question(
this, QTStr("ConfirmRemove.Title"), text);
if (button == QMessageBox::No)
return;
@ -358,13 +355,13 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
Load(newPath.c_str());
RefreshSceneCollections();
const char *newFile = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile");
const char *newFile = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile");
blog(LOG_INFO, "Removed scene collection '%s' (%s.json), "
"switched to '%s' (%s.json)",
oldName.c_str(), oldFile.c_str(),
newName.c_str(), newFile);
blog(LOG_INFO,
"Removed scene collection '%s' (%s.json), "
"switched to '%s' (%s.json)",
oldName.c_str(), oldFile.c_str(), newName.c_str(), newFile);
blog(LOG_INFO, "------------------------------------------------");
UpdateTitleBar();
@ -388,10 +385,8 @@ void OBSBasic::on_actionImportSceneCollection_triggered()
}
QString qfilePath = QFileDialog::getOpenFileName(
this,
QTStr("Basic.MainMenu.SceneCollection.Import"),
qhome,
"JSON Files (*.json)");
this, QTStr("Basic.MainMenu.SceneCollection.Import"), qhome,
"JSON Files (*.json)");
QFileInfo finfo(qfilePath);
QString qfilename = finfo.fileName();
@ -416,23 +411,25 @@ void OBSBasic::on_actionImportSceneCollection_triggered()
obs_data_set_string(scenedata, "name", name.c_str());
if (!GetFileSafeName(name.c_str(), file)) {
blog(LOG_WARNING, "Failed to create "
"safe file name for '%s'",
name.c_str());
blog(LOG_WARNING,
"Failed to create "
"safe file name for '%s'",
name.c_str());
return;
}
string filePath = path + file;
if (!GetClosestUnusedFileName(filePath, "json")) {
blog(LOG_WARNING, "Failed to get "
"closest file name for %s",
file.c_str());
blog(LOG_WARNING,
"Failed to get "
"closest file name for %s",
file.c_str());
return;
}
obs_data_save_json_safe(scenedata, filePath.c_str(),
"tmp", "bak");
obs_data_save_json_safe(scenedata, filePath.c_str(), "tmp",
"bak");
RefreshSceneCollections();
}
}
@ -445,8 +442,8 @@ void OBSBasic::on_actionExportSceneCollection_triggered()
QString home = QDir::homePath();
QString currentFile = QT_UTF8(config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile"));
QString currentFile = QT_UTF8(config_get_string(
App()->GlobalConfig(), "Basic", "SceneCollectionFile"));
int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
if (ret <= 0) {
@ -455,10 +452,8 @@ void OBSBasic::on_actionExportSceneCollection_triggered()
}
QString exportFile = QFileDialog::getSaveFileName(
this,
QTStr("Basic.MainMenu.SceneCollection.Export"),
home + "/" + currentFile,
"JSON Files (*.json)");
this, QTStr("Basic.MainMenu.SceneCollection.Export"),
home + "/" + currentFile, "JSON Files (*.json)");
string file = QT_TO_UTF8(exportFile);
@ -472,7 +467,7 @@ void OBSBasic::on_actionExportSceneCollection_triggered()
void OBSBasic::ChangeSceneCollection()
{
QAction *action = reinterpret_cast<QAction*>(sender());
QAction *action = reinterpret_cast<QAction *>(sender());
std::string fileName;
if (!action)
@ -482,8 +477,8 @@ void OBSBasic::ChangeSceneCollection()
if (fileName.empty())
return;
const char *oldName = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
const char *oldName = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
if (action->text().compare(QT_UTF8(oldName)) == 0) {
action->setChecked(true);
return;
@ -494,13 +489,13 @@ void OBSBasic::ChangeSceneCollection()
Load(fileName.c_str());
RefreshSceneCollections();
const char *newName = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
const char *newFile = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile");
const char *newName = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
const char *newFile = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile");
blog(LOG_INFO, "Switched to scene collection '%s' (%s.json)",
newName, newFile);
blog(LOG_INFO, "Switched to scene collection '%s' (%s.json)", newName,
newFile);
blog(LOG_INFO, "------------------------------------------------");
UpdateTitleBar();

View File

@ -54,8 +54,8 @@ void OBSBasic::InitDefaultTransitions()
if (!obs_is_source_configurable(id)) {
const char *name = obs_source_get_display_name(id);
obs_source_t *tr = obs_source_create_private(
id, name, NULL);
obs_source_t *tr =
obs_source_create_private(id, name, NULL);
InitTransition(tr);
transitions.emplace_back(tr);
@ -68,7 +68,7 @@ void OBSBasic::InitDefaultTransitions()
for (OBSSource &tr : transitions) {
ui->transitions->addItem(QT_UTF8(obs_source_get_name(tr)),
QVariant::fromValue(OBSSource(tr)));
QVariant::fromValue(OBSSource(tr)));
}
}
@ -79,33 +79,33 @@ void OBSBasic::AddQuickTransitionHotkey(QuickTransition *qt)
dstr_printf(hotkeyId, "OBSBasic.QuickTransition.%d", qt->id);
hotkeyName = QTStr("QuickTransitions.HotkeyName")
.arg(MakeQuickTransitionText(qt));
.arg(MakeQuickTransitionText(qt));
auto quickTransition = [] (void *data, obs_hotkey_id, obs_hotkey_t*,
bool pressed)
{
auto quickTransition = [](void *data, obs_hotkey_id, obs_hotkey_t *,
bool pressed) {
int id = (int)(uintptr_t)data;
OBSBasic *main =
reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
if (pressed)
QMetaObject::invokeMethod(main,
"TriggerQuickTransition",
Qt::QueuedConnection,
Q_ARG(int, id));
"TriggerQuickTransition",
Qt::QueuedConnection,
Q_ARG(int, id));
};
qt->hotkey = obs_hotkey_register_frontend(hotkeyId->array,
QT_TO_UTF8(hotkeyName), quickTransition,
(void*)(uintptr_t)qt->id);
QT_TO_UTF8(hotkeyName),
quickTransition,
(void *)(uintptr_t)qt->id);
}
void QuickTransition::SourceRenamed(void *param, calldata_t *data)
{
QuickTransition *qt = reinterpret_cast<QuickTransition*>(param);
QuickTransition *qt = reinterpret_cast<QuickTransition *>(param);
QString hotkeyName = QTStr("QuickTransitions.HotkeyName")
.arg(MakeQuickTransitionText(qt));
.arg(MakeQuickTransitionText(qt));
obs_hotkey_set_description(qt->hotkey, QT_TO_UTF8(hotkeyName));
@ -135,23 +135,23 @@ void OBSBasic::RemoveQuickTransitionHotkey(QuickTransition *qt)
void OBSBasic::InitTransition(obs_source_t *transition)
{
auto onTransitionStop = [] (void *data, calldata_t*) {
OBSBasic *window = (OBSBasic*)data;
auto onTransitionStop = [](void *data, calldata_t *) {
OBSBasic *window = (OBSBasic *)data;
QMetaObject::invokeMethod(window, "TransitionStopped",
Qt::QueuedConnection);
Qt::QueuedConnection);
};
auto onTransitionFullStop = [] (void *data, calldata_t*) {
OBSBasic *window = (OBSBasic*)data;
auto onTransitionFullStop = [](void *data, calldata_t *) {
OBSBasic *window = (OBSBasic *)data;
QMetaObject::invokeMethod(window, "TransitionFullyStopped",
Qt::QueuedConnection);
Qt::QueuedConnection);
};
signal_handler_t *handler = obs_source_get_signal_handler(transition);
signal_handler_connect(handler, "transition_video_stop",
onTransitionStop, this);
signal_handler_connect(handler, "transition_stop",
onTransitionFullStop, this);
onTransitionStop, this);
signal_handler_connect(handler, "transition_stop", onTransitionFullStop,
this);
}
static inline OBSSource GetTransitionComboItem(QComboBox *combo, int idx)
@ -163,12 +163,12 @@ void OBSBasic::CreateDefaultQuickTransitions()
{
/* non-configurable transitions are always available, so add them
* to the "default quick transitions" list */
quickTransitions.emplace_back(
GetTransitionComboItem(ui->transitions, 0),
300, quickTransitionIdCounter++);
quickTransitions.emplace_back(
GetTransitionComboItem(ui->transitions, 1),
300, quickTransitionIdCounter++);
quickTransitions.emplace_back(GetTransitionComboItem(ui->transitions,
0),
300, quickTransitionIdCounter++);
quickTransitions.emplace_back(GetTransitionComboItem(ui->transitions,
1),
300, quickTransitionIdCounter++);
}
void OBSBasic::LoadQuickTransitions(obs_data_array_t *array)
@ -188,13 +188,14 @@ void OBSBasic::LoadQuickTransitions(obs_data_array_t *array)
obs_source_t *source = FindTransition(name);
if (source) {
quickTransitions.emplace_back(source, duration,
id);
id);
if (quickTransitionIdCounter <= id)
quickTransitionIdCounter = id + 1;
int idx = (int)quickTransitions.size() - 1;
AddQuickTransitionHotkey(&quickTransitions[idx]);
AddQuickTransitionHotkey(
&quickTransitions[idx]);
obs_hotkey_load(quickTransitions[idx].hotkey,
hotkeys);
}
@ -214,7 +215,7 @@ obs_data_array_t *OBSBasic::SaveQuickTransitions()
obs_data_array_t *hotkeys = obs_hotkey_save(qt.hotkey);
obs_data_set_string(data, "name",
obs_source_get_name(qt.source));
obs_source_get_name(qt.source));
obs_data_set_int(data, "duration", qt.duration);
obs_data_set_array(data, "hotkeys", hotkeys);
obs_data_set_int(data, "id", qt.id);
@ -231,8 +232,7 @@ obs_data_array_t *OBSBasic::SaveQuickTransitions()
obs_source_t *OBSBasic::FindTransition(const char *name)
{
for (int i = 0; i < ui->transitions->count(); i++) {
OBSSource tr = ui->transitions->itemData(i)
.value<OBSSource>();
OBSSource tr = ui->transitions->itemData(i).value<OBSSource>();
const char *trName = obs_source_get_name(tr);
if (strcmp(trName, name) == 0)
@ -292,7 +292,7 @@ void OBSBasic::TransitionFullyStopped()
}
void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
bool quickTransition)
bool quickTransition)
{
obs_scene_t *scene = obs_scene_from_source(source);
bool usingPreviewProgram = IsPreviewProgramMode();
@ -317,10 +317,10 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
}
if (usingPreviewProgram && sceneDuplicationMode) {
scene = obs_scene_duplicate(scene, NULL,
editPropertiesMode ?
OBS_SCENE_DUP_PRIVATE_COPY :
OBS_SCENE_DUP_PRIVATE_REFS);
scene = obs_scene_duplicate(
scene, NULL,
editPropertiesMode ? OBS_SCENE_DUP_PRIVATE_COPY
: OBS_SCENE_DUP_PRIVATE_REFS);
source = obs_scene_get_source(scene);
}
@ -342,8 +342,8 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
OBSData data = obs_source_get_private_settings(source);
obs_data_release(data);
const char *trOverrideName = obs_data_get_string(data,
"transition");
const char *trOverrideName =
obs_data_get_string(data, "transition");
int duration = ui->transitionDuration->value();
if (trOverrideName && *trOverrideName && !quickTransition) {
@ -351,18 +351,18 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
if (trOverride) {
transition = trOverride;
obs_data_set_default_int(data,
"transition_duration", 300);
obs_data_set_default_int(
data, "transition_duration", 300);
duration = (int)obs_data_get_int(data,
"transition_duration");
duration = (int)obs_data_get_int(
data, "transition_duration");
OverrideTransition(trOverride);
overridingTransition = true;
}
}
bool success = obs_transition_start(transition,
OBS_TRANSITION_MODE_AUTO, duration, source);
bool success = obs_transition_start(
transition, OBS_TRANSITION_MODE_AUTO, duration, source);
if (!success)
TransitionFullyStopped();
}
@ -432,12 +432,12 @@ void OBSBasic::on_transitions_currentIndexChanged(int)
void OBSBasic::AddTransition()
{
QAction *action = reinterpret_cast<QAction*>(sender());
QAction *action = reinterpret_cast<QAction *>(sender());
QString idStr = action->property("id").toString();
string name;
QString placeHolderText = QT_UTF8(
obs_source_get_display_name(QT_TO_UTF8(idStr)));
QString placeHolderText =
QT_UTF8(obs_source_get_display_name(QT_TO_UTF8(idStr)));
QString format = placeHolderText + " (%1)";
obs_source_t *source = nullptr;
int i = 1;
@ -447,40 +447,41 @@ void OBSBasic::AddTransition()
}
bool accepted = NameDialog::AskForName(this,
QTStr("TransitionNameDlg.Title"),
QTStr("TransitionNameDlg.Text"),
name, placeHolderText);
QTStr("TransitionNameDlg.Title"),
QTStr("TransitionNameDlg.Text"),
name, placeHolderText);
if (accepted) {
if (name.empty()) {
OBSMessageBox::warning(this,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
AddTransition();
return;
}
source = FindTransition(name.c_str());
if (source) {
OBSMessageBox::warning(this,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
OBSMessageBox::warning(this, QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
AddTransition();
return;
}
source = obs_source_create_private(QT_TO_UTF8(idStr),
name.c_str(), NULL);
name.c_str(), NULL);
InitTransition(source);
ui->transitions->addItem(QT_UTF8(name.c_str()),
QVariant::fromValue(OBSSource(source)));
ui->transitions->addItem(
QT_UTF8(name.c_str()),
QVariant::fromValue(OBSSource(source)));
ui->transitions->setCurrentIndex(ui->transitions->count() - 1);
CreatePropertiesWindow(source);
obs_source_release(source);
if (api)
api->on_event(OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
api->on_event(
OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
ClearQuickTransitionWidgets();
RefreshQuickTransitions();
@ -500,8 +501,8 @@ void OBSBasic::on_transitionAdd_clicked()
QAction *action = new QAction(name, this);
action->setProperty("id", id);
connect(action, SIGNAL(triggered()),
this, SLOT(AddTransition()));
connect(action, SIGNAL(triggered()), this,
SLOT(AddTransition()));
menu.addAction(action);
foundConfigurableTransitions = true;
@ -529,7 +530,8 @@ void OBSBasic::on_transitionRemove_clicked()
if (qt.button)
qt.button->deleteLater();
RemoveQuickTransitionHotkey(&qt);
quickTransitions.erase(quickTransitions.begin() + i - 1);
quickTransitions.erase(quickTransitions.begin() + i -
1);
}
}
@ -544,7 +546,7 @@ void OBSBasic::on_transitionRemove_clicked()
void OBSBasic::RenameTransition()
{
QAction *action = reinterpret_cast<QAction*>(sender());
QAction *action = reinterpret_cast<QAction *>(sender());
QVariant variant = action->property("transition");
obs_source_t *transition = variant.value<OBSSource>();
@ -553,24 +555,23 @@ void OBSBasic::RenameTransition()
obs_source_t *source = nullptr;
bool accepted = NameDialog::AskForName(this,
QTStr("TransitionNameDlg.Title"),
QTStr("TransitionNameDlg.Text"),
name, placeHolderText);
QTStr("TransitionNameDlg.Title"),
QTStr("TransitionNameDlg.Text"),
name, placeHolderText);
if (accepted) {
if (name.empty()) {
OBSMessageBox::warning(this,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
RenameTransition();
return;
}
source = FindTransition(name.c_str());
if (source) {
OBSMessageBox::warning(this,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
OBSMessageBox::warning(this, QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
RenameTransition();
return;
@ -579,10 +580,12 @@ void OBSBasic::RenameTransition()
obs_source_set_name(transition, name.c_str());
int idx = ui->transitions->findData(variant);
if (idx != -1) {
ui->transitions->setItemText(idx, QT_UTF8(name.c_str()));
ui->transitions->setItemText(idx,
QT_UTF8(name.c_str()));
if (api)
api->on_event(OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
api->on_event(
OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
ClearQuickTransitionWidgets();
RefreshQuickTransitions();
@ -597,9 +600,7 @@ void OBSBasic::on_transitionProps_clicked()
if (!obs_source_configurable(source))
return;
auto properties = [&] () {
CreatePropertiesWindow(source);
};
auto properties = [&]() { CreatePropertiesWindow(source); };
QMenu menu(this);
@ -643,8 +644,7 @@ void OBSBasic::SetCurrentScene(obs_scene_t *scene, bool force, bool direct)
SetCurrentScene(source, force, direct);
}
template <typename T>
static T GetOBSRef(QListWidgetItem *item)
template<typename T> static T GetOBSRef(QListWidgetItem *item)
{
return item->data(static_cast<int>(QtDataRole::OBSRef)).value<T>();
}
@ -679,7 +679,8 @@ void OBSBasic::SetCurrentScene(OBSSource scene, bool force, bool direct)
ui->scenes->setCurrentItem(item);
ui->scenes->blockSignals(false);
if (api)
api->on_event(OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED);
api->on_event(
OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED);
break;
}
}
@ -689,8 +690,8 @@ void OBSBasic::SetCurrentScene(OBSSource scene, bool force, bool direct)
bool userSwitched = (!force && !disableSaving);
blog(LOG_INFO, "%s to scene '%s'",
userSwitched ? "User switched" : "Switched",
obs_source_get_name(scene));
userSwitched ? "User switched" : "Switched",
obs_source_get_name(scene));
}
void OBSBasic::CreateProgramDisplay()
@ -698,8 +699,8 @@ void OBSBasic::CreateProgramDisplay()
program = new OBSQTDisplay();
program->setContextMenuPolicy(Qt::CustomContextMenu);
connect(program.data(), &QWidget::customContextMenuRequested,
this, &OBSBasic::on_program_customContextMenuRequested);
connect(program.data(), &QWidget::customContextMenuRequested, this,
&OBSBasic::on_program_customContextMenuRequested);
auto displayResize = [this]() {
struct obs_video_info ovi;
@ -708,13 +709,11 @@ void OBSBasic::CreateProgramDisplay()
ResizeProgram(ovi.base_width, ovi.base_height);
};
connect(program.data(), &OBSQTDisplay::DisplayResized,
displayResize);
connect(program.data(), &OBSQTDisplay::DisplayResized, displayResize);
auto addDisplay = [this] (OBSQTDisplay *window)
{
auto addDisplay = [this](OBSQTDisplay *window) {
obs_display_add_draw_callback(window->GetDisplay(),
OBSBasic::RenderProgram, this);
OBSBasic::RenderProgram, this);
struct obs_video_info ovi;
if (obs_get_video_info(&ovi))
@ -723,8 +722,7 @@ void OBSBasic::CreateProgramDisplay()
connect(program.data(), &OBSQTDisplay::DisplayCreated, addDisplay);
program->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding);
program->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
void OBSBasic::TransitionClicked()
@ -771,16 +769,16 @@ void OBSBasic::CreateProgramOptions()
programOptions->setLayout(layout);
auto onAdd = [this] () {
auto onAdd = [this]() {
QScopedPointer<QMenu> menu(CreateTransitionMenu(this, nullptr));
menu->exec(QCursor::pos());
};
auto onConfig = [this] () {
auto onConfig = [this]() {
QMenu menu(this);
QAction *action;
auto toggleEditProperties = [this] () {
auto toggleEditProperties = [this]() {
editPropertiesMode = !editPropertiesMode;
OBSSource actualScene = OBSGetStrongRef(programScene);
@ -788,11 +786,11 @@ void OBSBasic::CreateProgramOptions()
TransitionToScene(actualScene, true);
};
auto toggleSwapScenesMode = [this] () {
auto toggleSwapScenesMode = [this]() {
swapScenesMode = !swapScenesMode;
};
auto toggleSceneDuplication = [this] () {
auto toggleSceneDuplication = [this]() {
sceneDuplicationMode = !sceneDuplicationMode;
OBSSource actualScene = OBSGetStrongRef(programScene);
@ -800,20 +798,22 @@ void OBSBasic::CreateProgramOptions()
TransitionToScene(actualScene, true);
};
auto showToolTip = [&] () {
auto showToolTip = [&]() {
QAction *act = menu.activeAction();
QToolTip::showText(QCursor::pos(), act->toolTip(),
&menu, menu.actionGeometry(act));
&menu, menu.actionGeometry(act));
};
action = menu.addAction(QTStr("QuickTransitions.DuplicateScene"));
action = menu.addAction(
QTStr("QuickTransitions.DuplicateScene"));
action->setToolTip(QTStr("QuickTransitions.DuplicateSceneTT"));
action->setCheckable(true);
action->setChecked(sceneDuplicationMode);
connect(action, &QAction::triggered, toggleSceneDuplication);
connect(action, &QAction::hovered, showToolTip);
action = menu.addAction(QTStr("QuickTransitions.EditProperties"));
action = menu.addAction(
QTStr("QuickTransitions.EditProperties"));
action->setToolTip(QTStr("QuickTransitions.EditPropertiesTT"));
action->setCheckable(true);
action->setChecked(editPropertiesMode);
@ -831,8 +831,8 @@ void OBSBasic::CreateProgramOptions()
menu.exec(QCursor::pos());
};
connect(transitionButton.data(), &QAbstractButton::clicked,
this, &OBSBasic::TransitionClicked);
connect(transitionButton.data(), &QAbstractButton::clicked, this,
&OBSBasic::TransitionClicked);
connect(addQuickTransition, &QAbstractButton::clicked, onAdd);
connect(configTransitions, &QAbstractButton::clicked, onConfig);
}
@ -868,8 +868,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
duration->setSingleStep(50);
duration->setValue(curDuration);
auto setTransition = [this] (QAction *action)
{
auto setTransition = [this](QAction *action) {
int idx = action->property("transition_index").toInt();
OBSSource scene = GetCurrentSceneSource();
OBSData data = obs_source_get_private_settings(scene);
@ -886,8 +885,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
obs_data_set_string(data, "transition", name);
};
auto setDuration = [this] (int duration)
{
auto setDuration = [this](int duration) {
OBSSource scene = GetCurrentSceneSource();
OBSData data = obs_source_get_private_settings(scene);
obs_data_release(data);
@ -895,8 +893,8 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
obs_data_set_int(data, "transition_duration", duration);
};
connect(duration, (void (QSpinBox::*)(int))&QSpinBox::valueChanged,
setDuration);
connect(duration, (void (QSpinBox::*)(int)) & QSpinBox::valueChanged,
setDuration);
for (int i = -1; i < ui->transitions->count(); i++) {
const char *name = "";
@ -918,7 +916,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
action->setChecked(match);
connect(action, &QAction::triggered,
std::bind(setTransition, action));
std::bind(setTransition, action));
}
QWidgetAction *durationAction = new QWidgetAction(menu);
@ -937,8 +935,8 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
if (qt) {
action = menu->addAction(QTStr("Remove"));
action->setProperty("id", qt->id);
connect(action, &QAction::triggered,
this, &OBSBasic::QuickTransitionRemoveClicked);
connect(action, &QAction::triggered, this,
&OBSBasic::QuickTransitionRemoveClicked);
menu->addSeparator();
}
@ -953,8 +951,9 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
duration->setValue(qt ? qt->duration : 300);
if (qt) {
connect(duration, (void (QSpinBox::*)(int))&QSpinBox::valueChanged,
this, &OBSBasic::QuickTransitionChangeDuration);
connect(duration,
(void (QSpinBox::*)(int)) & QSpinBox::valueChanged,
this, &OBSBasic::QuickTransitionChangeDuration);
}
for (int i = 0; i < ui->transitions->count(); i++) {
@ -966,12 +965,13 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
if (qt) {
action->setProperty("id", qt->id);
connect(action, &QAction::triggered, this,
&OBSBasic::QuickTransitionChange);
&OBSBasic::QuickTransitionChange);
} else {
action->setProperty("duration",
QVariant::fromValue<QWidget*>(duration));
action->setProperty(
"duration",
QVariant::fromValue<QWidget *>(duration));
connect(action, &QAction::triggered, this,
&OBSBasic::AddQuickTransition);
&OBSBasic::AddQuickTransition);
}
}
@ -1004,11 +1004,11 @@ void OBSBasic::AddQuickTransitionId(int id)
/* --------------------------------- */
button->setMenu(buttonMenu);
connect(button, &QAbstractButton::clicked,
this, &OBSBasic::QuickTransitionClicked);
connect(button, &QAbstractButton::clicked, this,
&OBSBasic::QuickTransitionClicked);
QVBoxLayout *programLayout =
reinterpret_cast<QVBoxLayout*>(programOptions->layout());
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
int idx = 3;
for (;; idx++) {
@ -1027,7 +1027,7 @@ void OBSBasic::AddQuickTransitionId(int id)
void OBSBasic::AddQuickTransition()
{
int trIdx = sender()->property("transition_index").toInt();
QSpinBox *duration = sender()->property("duration").value<QSpinBox*>();
QSpinBox *duration = sender()->property("duration").value<QSpinBox *>();
OBSSource transition = GetTransitionComboItem(ui->transitions, trIdx);
int id = quickTransitionIdCounter++;
@ -1048,7 +1048,7 @@ void OBSBasic::ClearQuickTransitions()
return;
QVBoxLayout *programLayout =
reinterpret_cast<QVBoxLayout*>(programOptions->layout());
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
for (int idx = 0;; idx++) {
QLayoutItem *item = programLayout->itemAt(idx);
@ -1118,7 +1118,7 @@ void OBSBasic::ClearQuickTransitionWidgets()
return;
QVBoxLayout *programLayout =
reinterpret_cast<QVBoxLayout*>(programOptions->layout());
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
for (int idx = 0;; idx++) {
QLayoutItem *item = programLayout->itemAt(idx);
@ -1152,7 +1152,7 @@ void OBSBasic::DisableQuickTransitionWidgets()
return;
QVBoxLayout *programLayout =
reinterpret_cast<QVBoxLayout*>(programOptions->layout());
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
for (int idx = 0;; idx++) {
QLayoutItem *item = programLayout->itemAt(idx);
@ -1173,7 +1173,7 @@ void OBSBasic::EnableQuickTransitionWidgets()
return;
QVBoxLayout *programLayout =
reinterpret_cast<QVBoxLayout*>(programOptions->layout());
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
for (int idx = 0;; idx++) {
QLayoutItem *item = programLayout->itemAt(idx);
@ -1209,10 +1209,11 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
obs_scene_t *dup;
if (sceneDuplicationMode) {
dup = obs_scene_duplicate(curScene, nullptr,
editPropertiesMode ?
OBS_SCENE_DUP_PRIVATE_COPY :
OBS_SCENE_DUP_PRIVATE_REFS);
dup = obs_scene_duplicate(
curScene, nullptr,
editPropertiesMode
? OBS_SCENE_DUP_PRIVATE_COPY
: OBS_SCENE_DUP_PRIVATE_REFS);
} else {
dup = curScene;
obs_scene_addref(dup);
@ -1235,7 +1236,7 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
programLabel = new QLabel(QTStr("StudioMode.Program"));
programLabel->setSizePolicy(QSizePolicy::Preferred,
QSizePolicy::Preferred);
QSizePolicy::Preferred);
programLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
programLabel->setProperty("themeID", "previewProgramLabels");
@ -1248,8 +1249,8 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
programLayout->addWidget(programLabel);
programLayout->addWidget(program);
bool labels = config_get_bool(GetGlobalConfig(),
"BasicWindow", "StudioModeLabels");
bool labels = config_get_bool(GetGlobalConfig(), "BasicWindow",
"StudioModeLabels");
programLabel->setHidden(!labels);
@ -1257,14 +1258,15 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
ui->previewLayout->addWidget(programOptions);
ui->previewLayout->addWidget(programWidget);
ui->previewLayout->setAlignment(programOptions, Qt::AlignCenter);
ui->previewLayout->setAlignment(programOptions,
Qt::AlignCenter);
if (api)
api->on_event(OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED);
blog(LOG_INFO, "Switched to Preview/Program mode");
blog(LOG_INFO, "-----------------------------"
"-------------------");
"-------------------");
} else {
OBSSource actualProgramScene = OBSGetStrongRef(programScene);
if (!actualProgramScene)
@ -1299,7 +1301,7 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
blog(LOG_INFO, "Switched to regular Preview mode");
blog(LOG_INFO, "-----------------------------"
"-------------------");
"-------------------");
}
ResetUI();
@ -1310,7 +1312,7 @@ void OBSBasic::RenderProgram(void *data, uint32_t cx, uint32_t cy)
{
GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "RenderProgram");
OBSBasic *window = static_cast<OBSBasic*>(data);
OBSBasic *window = static_cast<OBSBasic *>(data);
obs_video_info ovi;
obs_get_video_info(&ovi);
@ -1324,9 +1326,9 @@ void OBSBasic::RenderProgram(void *data, uint32_t cx, uint32_t cy)
/* --------------------------------------- */
gs_ortho(0.0f, float(ovi.base_width), 0.0f, float(ovi.base_height),
-100.0f, 100.0f);
gs_set_viewport(window->programX, window->programY,
window->programCX, window->programCY);
-100.0f, 100.0f);
gs_set_viewport(window->programX, window->programY, window->programCX,
window->programCY);
window->DrawBackdrop(float(ovi.base_width), float(ovi.base_height));
@ -1351,9 +1353,9 @@ void OBSBasic::ResizeProgram(uint32_t cx, uint32_t cy)
/* resize program panel to fix to the top section of the window */
targetSize = GetPixelSize(program);
GetScaleAndCenterPos(int(cx), int(cy),
targetSize.width() - PREVIEW_EDGE_SIZE * 2,
targetSize.height() - PREVIEW_EDGE_SIZE * 2,
programX, programY, programScale);
targetSize.width() - PREVIEW_EDGE_SIZE * 2,
targetSize.height() - PREVIEW_EDGE_SIZE * 2,
programX, programY, programScale);
programX += float(PREVIEW_EDGE_SIZE);
programY += float(PREVIEW_EDGE_SIZE);
@ -1371,7 +1373,8 @@ obs_data_array_t *OBSBasic::SaveTransitions()
obs_data_t *sourceData = obs_data_create();
obs_data_t *settings = obs_source_get_settings(tr);
obs_data_set_string(sourceData, "name", obs_source_get_name(tr));
obs_data_set_string(sourceData, "name",
obs_source_get_name(tr));
obs_data_set_string(sourceData, "id", obs_obj_get_id(tr));
obs_data_set_obj(sourceData, "settings", settings);
@ -1394,14 +1397,15 @@ void OBSBasic::LoadTransitions(obs_data_array_t *transitions)
const char *id = obs_data_get_string(item, "id");
obs_data_t *settings = obs_data_get_obj(item, "settings");
obs_source_t *source = obs_source_create_private(id, name,
settings);
obs_source_t *source =
obs_source_create_private(id, name, settings);
if (!obs_obj_invalid(source)) {
InitTransition(source);
ui->transitions->addItem(QT_UTF8(name),
QVariant::fromValue(OBSSource(source)));
ui->transitions->addItem(
QT_UTF8(name),
QVariant::fromValue(OBSSource(source)));
ui->transitions->setCurrentIndex(
ui->transitions->count() - 1);
ui->transitions->count() - 1);
}
obs_data_release(settings);

File diff suppressed because it is too large Load Diff

View File

@ -53,16 +53,16 @@ class OBSBasicStats;
#define DESKTOP_AUDIO_1 Str("DesktopAudioDevice1")
#define DESKTOP_AUDIO_2 Str("DesktopAudioDevice2")
#define AUX_AUDIO_1 Str("AuxAudioDevice1")
#define AUX_AUDIO_2 Str("AuxAudioDevice2")
#define AUX_AUDIO_3 Str("AuxAudioDevice3")
#define AUX_AUDIO_4 Str("AuxAudioDevice4")
#define AUX_AUDIO_1 Str("AuxAudioDevice1")
#define AUX_AUDIO_2 Str("AuxAudioDevice2")
#define AUX_AUDIO_3 Str("AuxAudioDevice3")
#define AUX_AUDIO_4 Str("AuxAudioDevice4")
#define SIMPLE_ENCODER_X264 "x264"
#define SIMPLE_ENCODER_X264_LOWCPU "x264_lowcpu"
#define SIMPLE_ENCODER_QSV "qsv"
#define SIMPLE_ENCODER_NVENC "nvenc"
#define SIMPLE_ENCODER_AMD "amd"
#define SIMPLE_ENCODER_X264 "x264"
#define SIMPLE_ENCODER_X264_LOWCPU "x264_lowcpu"
#define SIMPLE_ENCODER_QSV "qsv"
#define SIMPLE_ENCODER_NVENC "nvenc"
#define SIMPLE_ENCODER_AMD "amd"
#define PREVIEW_EDGE_SIZE 10
@ -89,13 +89,14 @@ struct QuickTransition {
inline QuickTransition() {}
inline QuickTransition(OBSSource source_, int duration_, int id_)
: source (source_),
duration (duration_),
id (id_),
renamedSignal (std::make_shared<OBSSignal>(
obs_source_get_signal_handler(source),
"rename", SourceRenamed, this))
{}
: source(source_),
duration(duration_),
id(id_),
renamedSignal(std::make_shared<OBSSignal>(
obs_source_get_signal_handler(source), "rename",
SourceRenamed, this))
{
}
private:
static void SourceRenamed(void *param, calldata_t *data);
@ -124,19 +125,14 @@ class OBSBasic : public OBSMainWindow {
friend class AutoConfigStreamPage;
friend struct OBSStudioAPI;
enum class MoveDir {
Up,
Down,
Left,
Right
};
enum class MoveDir { Up, Down, Left, Right };
enum DropType {
DropType_RawText,
DropType_Text,
DropType_Image,
DropType_Media,
DropType_Html
DropType_Html,
};
private:
@ -144,7 +140,7 @@ private:
std::shared_ptr<Auth> auth;
std::vector<VolControl*> volumes;
std::vector<VolControl *> volumes;
std::vector<OBSSignal> signalHandlers;
@ -172,7 +168,7 @@ private:
QPointer<QDockWidget> statsDock;
QPointer<OBSAbout> about;
QPointer<QTimer> cpuUsageTimer;
QPointer<QTimer> cpuUsageTimer;
os_cpu_usage_info_t *cpuUsageInfo = nullptr;
OBSService service;
@ -188,16 +184,16 @@ private:
gs_vertbuffer_t *boxBottom = nullptr;
gs_vertbuffer_t *circle = nullptr;
bool sceneChanging = false;
bool ignoreSelectionUpdate = false;
bool sceneChanging = false;
bool ignoreSelectionUpdate = false;
int previewX = 0, previewY = 0;
int previewCX = 0, previewCY = 0;
float previewScale = 0.0f;
int previewX = 0, previewY = 0;
int previewCX = 0, previewCY = 0;
float previewScale = 0.0f;
ConfigFile basicConfig;
ConfigFile basicConfig;
std::vector<SavedProjectorInfo*> savedProjectorsArray;
std::vector<SavedProjectorInfo *> savedProjectorsArray;
QPointer<QWidget> projectors[10];
QList<QPointer<QWidget>> windowProjectors;
@ -210,26 +206,26 @@ private:
QPointer<QPushButton> replayBufferButton;
QScopedPointer<QSystemTrayIcon> trayIcon;
QPointer<QAction> sysTrayStream;
QPointer<QAction> sysTrayRecord;
QPointer<QAction> sysTrayReplayBuffer;
QPointer<QAction> showHide;
QPointer<QAction> exit;
QPointer<QMenu> trayMenu;
QPointer<QMenu> previewProjector;
QPointer<QMenu> studioProgramProjector;
QPointer<QMenu> multiviewProjectorMenu;
QPointer<QMenu> previewProjectorSource;
QPointer<QMenu> previewProjectorMain;
QPointer<QMenu> sceneProjectorMenu;
QPointer<QMenu> sourceProjector;
QPointer<QMenu> scaleFilteringMenu;
QPointer<QMenu> colorMenu;
QPointer<QWidgetAction> colorWidgetAction;
QPointer<ColorSelect> colorSelect;
QPointer<QMenu> deinterlaceMenu;
QPointer<QMenu> perSceneTransitionMenu;
QPointer<QObject> shortcutFilter;
QPointer<QAction> sysTrayStream;
QPointer<QAction> sysTrayRecord;
QPointer<QAction> sysTrayReplayBuffer;
QPointer<QAction> showHide;
QPointer<QAction> exit;
QPointer<QMenu> trayMenu;
QPointer<QMenu> previewProjector;
QPointer<QMenu> studioProgramProjector;
QPointer<QMenu> multiviewProjectorMenu;
QPointer<QMenu> previewProjectorSource;
QPointer<QMenu> previewProjectorMain;
QPointer<QMenu> sceneProjectorMenu;
QPointer<QMenu> sourceProjector;
QPointer<QMenu> scaleFilteringMenu;
QPointer<QMenu> colorMenu;
QPointer<QWidgetAction> colorWidgetAction;
QPointer<ColorSelect> colorSelect;
QPointer<QMenu> deinterlaceMenu;
QPointer<QMenu> perSceneTransitionMenu;
QPointer<QObject> shortcutFilter;
QPointer<QWidget> programWidget;
QPointer<QVBoxLayout> programLayout;
@ -238,47 +234,47 @@ private:
QScopedPointer<QThread> patronJsonThread;
std::string patronJson;
void UpdateMultiviewProjectorMenu();
void UpdateMultiviewProjectorMenu();
void DrawBackdrop(float cx, float cy);
void DrawBackdrop(float cx, float cy);
void SetupEncoders();
void SetupEncoders();
void CreateFirstRunSources();
void CreateDefaultScene(bool firstStart);
void CreateFirstRunSources();
void CreateDefaultScene(bool firstStart);
void UpdateVolumeControlsDecayRate();
void UpdateVolumeControlsPeakMeterType();
void ClearVolumeControls();
void UpdateVolumeControlsDecayRate();
void UpdateVolumeControlsPeakMeterType();
void ClearVolumeControls();
void UploadLog(const char *subdir, const char *file);
void UploadLog(const char *subdir, const char *file);
void Save(const char *file);
void Load(const char *file);
void Save(const char *file);
void Load(const char *file);
void InitHotkeys();
void CreateHotkeys();
void ClearHotkeys();
void InitHotkeys();
void CreateHotkeys();
void ClearHotkeys();
bool InitService();
bool InitService();
bool InitBasicConfigDefaults();
void InitBasicConfigDefaults2();
bool InitBasicConfig();
bool InitBasicConfigDefaults();
void InitBasicConfigDefaults2();
bool InitBasicConfig();
void InitOBSCallbacks();
void InitOBSCallbacks();
void InitPrimitives();
void InitPrimitives();
void OnFirstLoad();
void OnFirstLoad();
OBSSceneItem GetSceneItem(QListWidgetItem *item);
OBSSceneItem GetCurrentSceneItem();
OBSSceneItem GetSceneItem(QListWidgetItem *item);
OBSSceneItem GetCurrentSceneItem();
bool QueryRemoveSource(obs_source_t *source);
bool QueryRemoveSource(obs_source_t *source);
void TimedCheckForUpdates();
void CheckForUpdates(bool manualUpdate);
void TimedCheckForUpdates();
void CheckForUpdates(bool manualUpdate);
void GetFPSCommon(uint32_t &num, uint32_t &den) const;
void GetFPSInteger(uint32_t &num, uint32_t &den) const;
@ -293,8 +289,8 @@ private:
void ChangeSceneIndex(bool relative, int idx, int invalidIdx);
void TempFileOutput(const char *path, int vBitrate, int aBitrate);
void TempStreamOutput(const char *url, const char *key,
int vBitrate, int aBitrate);
void TempStreamOutput(const char *url, const char *key, int vBitrate,
int aBitrate);
void CloseDialogs();
void ClearSceneData();
@ -302,7 +298,7 @@ private:
void Nudge(int dist, MoveDir dir);
OBSProjector *OpenProjector(obs_source_t *source, int monitor,
QString title, ProjectorType type);
QString title, ProjectorType type);
void GetAudioSourceFilters();
void GetAudioSourceProperties();
@ -327,8 +323,8 @@ private:
int GetTopSelectedSourceItem();
obs_hotkey_pair_id streamingHotkeys, recordingHotkeys,
replayBufHotkeys, togglePreviewHotkeys;
obs_hotkey_pair_id streamingHotkeys, recordingHotkeys, replayBufHotkeys,
togglePreviewHotkeys;
obs_hotkey_id forceStreamingStopHotkey;
void InitDefaultTransitions();
@ -368,7 +364,7 @@ private:
void SetPreviewProgramMode(bool enabled);
void ResizeProgram(uint32_t cx, uint32_t cy);
void SetCurrentScene(obs_scene_t *scene, bool force = false,
bool direct = false);
bool direct = false);
static void RenderProgram(void *data, uint32_t cx, uint32_t cy);
std::vector<QuickTransition> quickTransitions;
@ -386,8 +382,8 @@ private:
int quickTransitionIdCounter = 1;
bool overridingTransition = false;
int programX = 0, programY = 0;
int programCX = 0, programCY = 0;
int programX = 0, programY = 0;
int programCX = 0, programCY = 0;
float programScale = 0.0f;
int disableOutputsRef = 0;
@ -407,9 +403,9 @@ private:
void EnumDialogs();
QList<QDialog*> visDialogs;
QList<QDialog*> modalDialogs;
QList<QMessageBox*> visMsgBoxes;
QList<QDialog *> visDialogs;
QList<QDialog *> modalDialogs;
QList<QMessageBox *> visMsgBoxes;
QList<QPoint> visDlgPositions;
@ -457,15 +453,15 @@ public slots:
void SetTransition(OBSSource transition);
void TransitionToScene(OBSScene scene, bool force = false,
bool direct = false);
bool direct = false);
void TransitionToScene(OBSSource scene, bool force = false,
bool direct = false, bool quickTransition = false);
bool direct = false,
bool quickTransition = false);
void SetCurrentScene(OBSSource scene, bool force = false,
bool direct = false);
bool direct = false);
bool AddSceneCollection(
bool create_new,
const QString &name = QString());
bool AddSceneCollection(bool create_new,
const QString &name = QString());
void UpdatePatronJson(const QString &text, const QString &error);
@ -575,7 +571,7 @@ public:
}
obs_service_t *GetService();
void SetService(obs_service_t *service);
void SetService(obs_service_t *service);
int GetTransitionDuration();
@ -588,29 +584,26 @@ public:
bool Active() const;
void ResetUI();
int ResetVideo();
int ResetVideo();
bool ResetAudio();
void ResetOutputs();
void ResetAudioDevice(const char *sourceId, const char *deviceId,
const char *deviceDesc, int channel);
const char *deviceDesc, int channel);
void NewProject();
void LoadProject();
inline void GetDisplayRect(int &x, int &y, int &cx, int &cy)
{
x = previewX;
y = previewY;
x = previewX;
y = previewY;
cx = previewCX;
cy = previewCY;
}
inline bool SavingDisabled() const
{
return disableSaving;
}
inline bool SavingDisabled() const { return disableSaving; }
inline double GetCPUUsage() const
{
@ -620,7 +613,7 @@ public:
void SaveService();
bool LoadService();
inline Auth *GetAuth() {return auth.get();}
inline Auth *GetAuth() { return auth.get(); }
inline void EnableOutputs(bool enable)
{
@ -635,7 +628,8 @@ public:
QMenu *AddDeinterlacingMenu(QMenu *menu, obs_source_t *source);
QMenu *AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item);
QMenu *AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction,
ColorSelect *select, obs_sceneitem_t *item);
ColorSelect *select,
obs_sceneitem_t *item);
void CreateSourcePopupMenu(int idx, bool preview);
void UpdateTitleBar();
@ -691,7 +685,7 @@ private slots:
void on_actionHorizontalCenter_triggered();
void on_scenes_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *prev);
QListWidgetItem *prev);
void on_scenes_customContextMenuRequested(const QPoint &pos);
void on_actionAddScene_triggered();
void on_actionRemoveScene_triggered();
@ -728,8 +722,8 @@ private slots:
void on_preview_customContextMenuRequested(const QPoint &pos);
void on_program_customContextMenuRequested(const QPoint &pos);
void on_previewDisabledLabel_customContextMenuRequested(
const QPoint &pos);
void
on_previewDisabledLabel_customContextMenuRequested(const QPoint &pos);
void on_actionNewSceneCollection_triggered();
void on_actionDupSceneCollection_triggered();
@ -779,7 +773,7 @@ private slots:
void EditSceneItemName();
void SceneNameEdited(QWidget *editor,
QAbstractItemDelegate::EndEditHint endHint);
QAbstractItemDelegate::EndEditHint endHint);
void OpenSceneFilters();
void OpenFilters();
@ -825,8 +819,8 @@ public:
virtual config_t *Config() const override;
virtual int GetProfilePath(char *path, size_t size, const char *file)
const override;
virtual int GetProfilePath(char *path, size_t size,
const char *file) const override;
static void InitBrowserPanelSafeBlock();
@ -839,8 +833,8 @@ class SceneRenameDelegate : public QStyledItemDelegate {
public:
SceneRenameDelegate(QObject *parent);
virtual void setEditorData(QWidget *editor, const QModelIndex &index)
const override;
virtual void setEditorData(QWidget *editor,
const QModelIndex &index) const override;
protected:
virtual bool eventFilter(QObject *editor, QEvent *event) override;

View File

@ -11,7 +11,7 @@
#include "obs-app.hpp"
#include "platform.hpp"
#define HANDLE_RADIUS 4.0f
#define HANDLE_RADIUS 4.0f
#define HANDLE_SEL_RADIUS (HANDLE_RADIUS * 1.5f)
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
#define SUPPORTS_FRACTIONAL_SCALING
@ -37,7 +37,7 @@ OBSBasicPreview::~OBSBasicPreview()
vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
#ifdef SUPPORTS_FRACTIONAL_SCALING
float pixelRatio = main->devicePixelRatioF();
#else
@ -46,28 +46,28 @@ vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event)
float scale = pixelRatio / main->previewScale;
vec2 pos;
vec2_set(&pos,
(float(event->x()) - main->previewX / pixelRatio) * scale,
(float(event->y()) - main->previewY / pixelRatio) * scale);
(float(event->x()) - main->previewX / pixelRatio) * scale,
(float(event->y()) - main->previewY / pixelRatio) * scale);
return pos;
}
struct SceneFindData {
const vec2 &pos;
const vec2 &pos;
OBSSceneItem item;
bool selectBelow;
bool selectBelow;
obs_sceneitem_t *group = nullptr;
SceneFindData(const SceneFindData &) = delete;
SceneFindData(SceneFindData &&) = delete;
SceneFindData& operator=(const SceneFindData &) = delete;
SceneFindData& operator=(SceneFindData &&) = delete;
SceneFindData &operator=(const SceneFindData &) = delete;
SceneFindData &operator=(SceneFindData &&) = delete;
inline SceneFindData(const vec2 &pos_, bool selectBelow_)
: pos (pos_),
selectBelow (selectBelow_)
{}
: pos(pos_), selectBelow(selectBelow_)
{
}
};
static bool SceneItemHasVideo(obs_sceneitem_t *item)
@ -77,21 +77,21 @@ static bool SceneItemHasVideo(obs_sceneitem_t *item)
return (flags & OBS_SOURCE_VIDEO) != 0;
}
static bool CloseFloat(float a, float b, float epsilon=0.01)
static bool CloseFloat(float a, float b, float epsilon = 0.01)
{
using std::abs;
return abs(a-b) <= epsilon;
return abs(a - b) <= epsilon;
}
static bool FindItemAtPos(obs_scene_t *scene, obs_sceneitem_t *item,
void *param)
void *param)
{
SceneFindData *data = reinterpret_cast<SceneFindData*>(param);
matrix4 transform;
matrix4 invTransform;
vec3 transformedPos;
vec3 pos3;
vec3 pos3_;
SceneFindData *data = reinterpret_cast<SceneFindData *>(param);
matrix4 transform;
matrix4 invTransform;
vec3 transformedPos;
vec3 pos3;
vec3 pos3_;
if (!SceneItemHasVideo(item))
return true;
@ -147,54 +147,50 @@ static inline vec2 GetOBSScreenSize()
vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
vec2 screenSize = GetOBSScreenSize();
vec3 clampOffset;
vec3_zero(&clampOffset);
const bool snap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "SnappingEnabled");
const bool snap = config_get_bool(GetGlobalConfig(), "BasicWindow",
"SnappingEnabled");
if (snap == false)
return clampOffset;
const bool screenSnap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "ScreenSnapping");
const bool centerSnap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "CenterSnapping");
const bool screenSnap = config_get_bool(
GetGlobalConfig(), "BasicWindow", "ScreenSnapping");
const bool centerSnap = config_get_bool(
GetGlobalConfig(), "BasicWindow", "CenterSnapping");
const float clampDist = config_get_double(GetGlobalConfig(),
"BasicWindow", "SnapDistance") / main->previewScale;
"BasicWindow",
"SnapDistance") /
main->previewScale;
const float centerX = br.x - (br.x - tl.x) / 2.0f;
const float centerY = br.y - (br.y - tl.y) / 2.0f;
// Left screen edge.
if (screenSnap &&
fabsf(tl.x) < clampDist)
if (screenSnap && fabsf(tl.x) < clampDist)
clampOffset.x = -tl.x;
// Right screen edge.
if (screenSnap &&
fabsf(clampOffset.x) < EPSILON &&
if (screenSnap && fabsf(clampOffset.x) < EPSILON &&
fabsf(screenSize.x - br.x) < clampDist)
clampOffset.x = screenSize.x - br.x;
// Horizontal center.
if (centerSnap &&
fabsf(screenSize.x - (br.x - tl.x)) > clampDist &&
if (centerSnap && fabsf(screenSize.x - (br.x - tl.x)) > clampDist &&
fabsf(screenSize.x / 2.0f - centerX) < clampDist)
clampOffset.x = screenSize.x / 2.0f - centerX;
// Top screen edge.
if (screenSnap &&
fabsf(tl.y) < clampDist)
if (screenSnap && fabsf(tl.y) < clampDist)
clampOffset.y = -tl.y;
// Bottom screen edge.
if (screenSnap &&
fabsf(clampOffset.y) < EPSILON &&
if (screenSnap && fabsf(clampOffset.y) < EPSILON &&
fabsf(screenSize.y - br.y) < clampDist)
clampOffset.y = screenSize.y - br.y;
// Vertical center.
if (centerSnap &&
fabsf(screenSize.y - (br.y - tl.y)) > clampDist &&
if (centerSnap && fabsf(screenSize.y - (br.y - tl.y)) > clampDist &&
fabsf(screenSize.y / 2.0f - centerY) < clampDist)
clampOffset.y = screenSize.y / 2.0f - centerY;
@ -203,7 +199,7 @@ vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br)
OBSSceneItem OBSBasicPreview::GetItemAtPos(const vec2 &pos, bool selectBelow)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
if (!scene)
@ -215,12 +211,12 @@ OBSSceneItem OBSBasicPreview::GetItemAtPos(const vec2 &pos, bool selectBelow)
}
static bool CheckItemSelected(obs_scene_t *scene, obs_sceneitem_t *item,
void *param)
void *param)
{
SceneFindData *data = reinterpret_cast<SceneFindData*>(param);
matrix4 transform;
vec3 transformedPos;
vec3 pos3;
SceneFindData *data = reinterpret_cast<SceneFindData *>(param);
matrix4 transform;
vec3 transformedPos;
vec3 pos3;
if (!SceneItemHasVideo(item))
return true;
@ -240,7 +236,8 @@ static bool CheckItemSelected(obs_scene_t *scene, obs_sceneitem_t *item,
if (data->group) {
matrix4 parent_transform;
obs_sceneitem_get_draw_transform(data->group, &parent_transform);
obs_sceneitem_get_draw_transform(data->group,
&parent_transform);
matrix4_mul(&transform, &transform, &parent_transform);
}
@ -261,7 +258,7 @@ static bool CheckItemSelected(obs_scene_t *scene, obs_sceneitem_t *item,
bool OBSBasicPreview::SelectedAtPos(const vec2 &pos)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
if (!scene)
@ -273,46 +270,45 @@ bool OBSBasicPreview::SelectedAtPos(const vec2 &pos)
}
struct HandleFindData {
const vec2 &pos;
const float radius;
matrix4 parent_xform;
const vec2 &pos;
const float radius;
matrix4 parent_xform;
OBSSceneItem item;
ItemHandle handle = ItemHandle::None;
ItemHandle handle = ItemHandle::None;
HandleFindData(const HandleFindData &) = delete;
HandleFindData(HandleFindData &&) = delete;
HandleFindData& operator=(const HandleFindData &) = delete;
HandleFindData& operator=(HandleFindData &&) = delete;
HandleFindData &operator=(const HandleFindData &) = delete;
HandleFindData &operator=(HandleFindData &&) = delete;
inline HandleFindData(const vec2 &pos_, float scale)
: pos (pos_),
radius (HANDLE_SEL_RADIUS / scale)
: pos(pos_), radius(HANDLE_SEL_RADIUS / scale)
{
matrix4_identity(&parent_xform);
}
inline HandleFindData(const HandleFindData &hfd,
obs_sceneitem_t *parent)
: pos (hfd.pos),
radius (hfd.radius),
item (hfd.item),
handle (hfd.handle)
obs_sceneitem_t *parent)
: pos(hfd.pos),
radius(hfd.radius),
item(hfd.item),
handle(hfd.handle)
{
obs_sceneitem_get_draw_transform(parent, &parent_xform);
}
};
static bool FindHandleAtPos(obs_scene_t *scene, obs_sceneitem_t *item,
void *param)
void *param)
{
HandleFindData &data = *reinterpret_cast<HandleFindData*>(param);
HandleFindData &data = *reinterpret_cast<HandleFindData *>(param);
if (!obs_sceneitem_selected(item)) {
if (obs_sceneitem_is_group(item)) {
HandleFindData newData(data, item);
obs_sceneitem_group_enum_items(item, FindHandleAtPos,
&newData);
&newData);
data.item = newData.item;
data.handle = newData.handle;
}
@ -320,16 +316,15 @@ static bool FindHandleAtPos(obs_scene_t *scene, obs_sceneitem_t *item,
return true;
}
matrix4 transform;
vec3 pos3;
float closestHandle = data.radius;
matrix4 transform;
vec3 pos3;
float closestHandle = data.radius;
vec3_set(&pos3, data.pos.x, data.pos.y, 0.0f);
obs_sceneitem_get_box_transform(item, &transform);
auto TestHandle = [&] (float x, float y, ItemHandle handle)
{
auto TestHandle = [&](float x, float y, ItemHandle handle) {
vec3 handlePos = GetTransformedPos(x, y, transform);
vec3_transform(&handlePos, &handlePos, &data.parent_xform);
@ -337,8 +332,8 @@ static bool FindHandleAtPos(obs_scene_t *scene, obs_sceneitem_t *item,
if (dist < data.radius) {
if (dist < closestHandle) {
closestHandle = dist;
data.handle = handle;
data.item = item;
data.handle = handle;
data.item = item;
}
}
};
@ -370,10 +365,12 @@ static vec2 GetItemSize(obs_sceneitem_t *item)
obs_sceneitem_get_scale(item, &scale);
obs_sceneitem_get_crop(item, &crop);
size.x = float(obs_source_get_width(source) -
crop.left - crop.right) * scale.x;
size.y = float(obs_source_get_height(source) -
crop.top - crop.bottom) * scale.y;
size.x = float(obs_source_get_width(source) - crop.left -
crop.right) *
scale.x;
size.y = float(obs_source_get_height(source) - crop.top -
crop.bottom) *
scale.y;
}
return size;
@ -381,7 +378,7 @@ static vec2 GetItemSize(obs_sceneitem_t *item)
void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
if (!scene)
@ -397,13 +394,13 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
HandleFindData data(scaled_pos, scale);
obs_scene_enum_items(scene, FindHandleAtPos, &data);
stretchItem = std::move(data.item);
stretchHandle = data.handle;
stretchItem = std::move(data.item);
stretchHandle = data.handle;
if (stretchHandle != ItemHandle::None) {
matrix4 boxTransform;
vec3 itemUL;
float itemRot;
vec3 itemUL;
float itemRot;
stretchItemSize = GetItemSize(stretchItem);
@ -413,32 +410,31 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
/* build the item space conversion matrices */
matrix4_identity(&itemToScreen);
matrix4_rotate_aa4f(&itemToScreen, &itemToScreen,
0.0f, 0.0f, 1.0f, RAD(itemRot));
matrix4_translate3f(&itemToScreen, &itemToScreen,
itemUL.x, itemUL.y, 0.0f);
matrix4_rotate_aa4f(&itemToScreen, &itemToScreen, 0.0f, 0.0f,
1.0f, RAD(itemRot));
matrix4_translate3f(&itemToScreen, &itemToScreen, itemUL.x,
itemUL.y, 0.0f);
matrix4_identity(&screenToItem);
matrix4_translate3f(&screenToItem, &screenToItem,
-itemUL.x, -itemUL.y, 0.0f);
matrix4_rotate_aa4f(&screenToItem, &screenToItem,
0.0f, 0.0f, 1.0f, RAD(-itemRot));
matrix4_translate3f(&screenToItem, &screenToItem, -itemUL.x,
-itemUL.y, 0.0f);
matrix4_rotate_aa4f(&screenToItem, &screenToItem, 0.0f, 0.0f,
1.0f, RAD(-itemRot));
obs_sceneitem_get_crop(stretchItem, &startCrop);
obs_sceneitem_get_pos(stretchItem, &startItemPos);
obs_source_t *source = obs_sceneitem_get_source(stretchItem);
cropSize.x = float(obs_source_get_width(source) -
startCrop.left - startCrop.right);
startCrop.left - startCrop.right);
cropSize.y = float(obs_source_get_height(source) -
startCrop.top - startCrop.bottom);
startCrop.top - startCrop.bottom);
stretchGroup = obs_sceneitem_get_group(scene, stretchItem);
if (stretchGroup) {
obs_sceneitem_get_draw_transform(stretchGroup,
&invGroupTransform);
matrix4_inv(&invGroupTransform,
&invGroupTransform);
&invGroupTransform);
matrix4_inv(&invGroupTransform, &invGroupTransform);
obs_sceneitem_defer_group_resize_begin(stretchGroup);
}
}
@ -480,8 +476,8 @@ void OBSBasicPreview::keyReleaseEvent(QKeyEvent *event)
void OBSBasicPreview::wheelEvent(QWheelEvent *event)
{
if (scrollMode && IsFixedScaling()
&& event->orientation() == Qt::Vertical) {
if (scrollMode && IsFixedScaling() &&
event->orientation() == Qt::Vertical) {
if (event->delta() > 0)
SetScalingLevel(scalingLevel + 1);
else if (event->delta() < 0)
@ -512,7 +508,7 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event)
return;
}
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
#ifdef SUPPORTS_FRACTIONAL_SCALING
float pixelRatio = main->devicePixelRatioF();
#else
@ -549,7 +545,7 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event)
static bool select_one(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
{
obs_sceneitem_t *selectedItem =
reinterpret_cast<obs_sceneitem_t*>(param);
reinterpret_cast<obs_sceneitem_t *>(param);
if (obs_sceneitem_is_group(item))
obs_sceneitem_group_enum_items(item, select_one, param);
@ -561,12 +557,12 @@ static bool select_one(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
void OBSBasicPreview::DoSelect(const vec2 &pos)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
OBSSceneItem item = GetItemAtPos(pos, true);
OBSScene scene = main->GetCurrentScene();
OBSSceneItem item = GetItemAtPos(pos, true);
obs_scene_enum_items(scene, select_one, (obs_sceneitem_t*)item);
obs_scene_enum_items(scene, select_one, (obs_sceneitem_t *)item);
}
void OBSBasicPreview::DoCtrlSelect(const vec2 &pos)
@ -609,11 +605,11 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event)
obs_sceneitem_defer_group_resize_end(stretchGroup);
}
stretchItem = nullptr;
stretchItem = nullptr;
stretchGroup = nullptr;
mouseDown = false;
mouseMoved = false;
cropping = false;
mouseDown = false;
mouseMoved = false;
cropping = false;
OBSSceneItem item = GetItemAtPos(pos, true);
hoveredPreviewItem = item;
@ -626,13 +622,13 @@ struct SelectedItemBounds {
};
static bool AddItemBounds(obs_scene_t *scene, obs_sceneitem_t *item,
void *param)
void *param)
{
SelectedItemBounds *data = reinterpret_cast<SelectedItemBounds*>(param);
SelectedItemBounds *data =
reinterpret_cast<SelectedItemBounds *>(param);
vec3 t[4];
auto add_bounds = [data, &t] ()
{
auto add_bounds = [data, &t]() {
for (const vec3 &v : t) {
if (data->first) {
vec3_copy(&data->tl, &v);
@ -686,9 +682,9 @@ struct OffsetData {
};
static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item,
void *param)
void *param)
{
OffsetData *data = reinterpret_cast<OffsetData*>(param);
OffsetData *data = reinterpret_cast<OffsetData *>(param);
if (obs_sceneitem_selected(item))
return true;
@ -696,12 +692,10 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item,
matrix4 boxTransform;
obs_sceneitem_get_box_transform(item, &boxTransform);
vec3 t[4] = {
GetTransformedPos(0.0f, 0.0f, boxTransform),
GetTransformedPos(1.0f, 0.0f, boxTransform),
GetTransformedPos(0.0f, 1.0f, boxTransform),
GetTransformedPos(1.0f, 1.0f, boxTransform)
};
vec3 t[4] = {GetTransformedPos(0.0f, 0.0f, boxTransform),
GetTransformedPos(1.0f, 0.0f, boxTransform),
GetTransformedPos(0.0f, 1.0f, boxTransform),
GetTransformedPos(1.0f, 1.0f, boxTransform)};
bool first = true;
vec3 tl, br;
@ -719,15 +713,15 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item,
}
// Snap to other source edges
#define EDGE_SNAP(l, r, x, y) \
do { \
double dist = fabsf(l.x - data->r.x); \
if (dist < data->clampDist && \
fabsf(data->offset.x) < EPSILON && \
data->tl.y < br.y && \
data->br.y > tl.y && \
(fabsf(data->offset.x) > dist || data->offset.x < EPSILON)) \
data->offset.x = l.x - data->r.x; \
#define EDGE_SNAP(l, r, x, y) \
do { \
double dist = fabsf(l.x - data->r.x); \
if (dist < data->clampDist && \
fabsf(data->offset.x) < EPSILON && data->tl.y < br.y && \
data->br.y > tl.y && \
(fabsf(data->offset.x) > dist || \
data->offset.x < EPSILON)) \
data->offset.x = l.x - data->r.x; \
} while (false)
EDGE_SNAP(tl, br, x, y);
@ -742,7 +736,7 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item,
void OBSBasicPreview::SnapItemMovement(vec2 &offset)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
SelectedItemBounds data;
@ -755,10 +749,10 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset)
vec3 snapOffset = GetSnapOffset(data.tl, data.br);
const bool snap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "SnappingEnabled");
const bool sourcesSnap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "SourceSnapping");
const bool snap = config_get_bool(GetGlobalConfig(), "BasicWindow",
"SnappingEnabled");
const bool sourcesSnap = config_get_bool(
GetGlobalConfig(), "BasicWindow", "SourceSnapping");
if (snap == false)
return;
if (sourcesSnap == false) {
@ -768,7 +762,9 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset)
}
const float clampDist = config_get_double(GetGlobalConfig(),
"BasicWindow", "SnapDistance") / main->previewScale;
"BasicWindow",
"SnapDistance") /
main->previewScale;
OffsetData offsetData;
offsetData.clampDist = clampDist;
@ -794,7 +790,7 @@ static bool move_items(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
return true;
bool selected = obs_sceneitem_selected(item);
vec2 *offset = reinterpret_cast<vec2*>(param);
vec2 *offset = reinterpret_cast<vec2 *>(param);
if (obs_sceneitem_is_group(item) && !selected) {
matrix4 transform;
@ -822,7 +818,7 @@ static bool move_items(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
void OBSBasicPreview::MoveItems(const vec2 &pos)
{
Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers();
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
vec2 offset, moveOffset;
@ -862,14 +858,14 @@ vec3 OBSBasicPreview::CalculateStretchPos(const vec3 &tl, const vec3 &br)
}
void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size,
const vec2 &baseSize)
const vec2 &baseSize)
{
float baseAspect = baseSize.x / baseSize.y;
float aspect = size.x / size.y;
float baseAspect = baseSize.x / baseSize.y;
float aspect = size.x / size.y;
uint32_t stretchFlags = (uint32_t)stretchHandle;
if (stretchHandle == ItemHandle::TopLeft ||
stretchHandle == ItemHandle::TopRight ||
if (stretchHandle == ItemHandle::TopLeft ||
stretchHandle == ItemHandle::TopRight ||
stretchHandle == ItemHandle::BottomLeft ||
stretchHandle == ItemHandle::BottomRight) {
if (aspect < baseAspect) {
@ -887,7 +883,7 @@ void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size,
}
} else if (stretchHandle == ItemHandle::TopCenter ||
stretchHandle == ItemHandle::BottomCenter) {
stretchHandle == ItemHandle::BottomCenter) {
if ((size.y >= 0.0f && size.x >= 0.0f) ||
(size.y <= 0.0f && size.x <= 0.0f))
size.x = size.y * baseAspect;
@ -895,7 +891,7 @@ void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size,
size.x = size.y * baseAspect * -1.0f;
} else if (stretchHandle == ItemHandle::CenterLeft ||
stretchHandle == ItemHandle::CenterRight) {
stretchHandle == ItemHandle::CenterRight) {
if ((size.y >= 0.0f && size.x >= 0.0f) ||
(size.y <= 0.0f && size.x <= 0.0f))
size.y = size.x / baseAspect;
@ -920,12 +916,12 @@ void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size,
void OBSBasicPreview::SnapStretchingToScreen(vec3 &tl, vec3 &br)
{
uint32_t stretchFlags = (uint32_t)stretchHandle;
vec3 newTL = GetTransformedPos(tl.x, tl.y, itemToScreen);
vec3 newTR = GetTransformedPos(br.x, tl.y, itemToScreen);
vec3 newBL = GetTransformedPos(tl.x, br.y, itemToScreen);
vec3 newBR = GetTransformedPos(br.x, br.y, itemToScreen);
vec3 boundingTL;
vec3 boundingBR;
vec3 newTL = GetTransformedPos(tl.x, tl.y, itemToScreen);
vec3 newTR = GetTransformedPos(br.x, tl.y, itemToScreen);
vec3 newBL = GetTransformedPos(tl.x, br.y, itemToScreen);
vec3 newBR = GetTransformedPos(br.x, br.y, itemToScreen);
vec3 boundingTL;
vec3 boundingBR;
vec3_copy(&boundingTL, &newTL);
vec3_min(&boundingTL, &boundingTL, &newTR);
@ -984,14 +980,12 @@ void OBSBasicPreview::CropItem(const vec2 &pos)
vec2 max_tl;
vec2 max_br;
vec2_set(&max_tl,
float(-crop.left) * scale.x,
float(-crop.top) * scale.y);
vec2_set(&max_br,
stretchItemSize.x + crop.right * scale.x,
stretchItemSize.y + crop.bottom * scale.y);
vec2_set(&max_tl, float(-crop.left) * scale.x,
float(-crop.top) * scale.y);
vec2_set(&max_br, stretchItemSize.x + crop.right * scale.x,
stretchItemSize.y + crop.bottom * scale.y);
typedef std::function<float (float, float)> minmax_func_t;
typedef std::function<float(float, float)> minmax_func_t;
minmax_func_t min_x = scale.x < 0.0f ? maxfunc : minfunc;
minmax_func_t min_y = scale.y < 0.0f ? maxfunc : minfunc;
@ -1021,8 +1015,8 @@ void OBSBasicPreview::CropItem(const vec2 &pos)
pos3.y = br.y = max_y(pos3.y, minY);
}
#define ALIGN_X (ITEM_LEFT|ITEM_RIGHT)
#define ALIGN_Y (ITEM_TOP|ITEM_BOTTOM)
#define ALIGN_X (ITEM_LEFT | ITEM_RIGHT)
#define ALIGN_Y (ITEM_TOP | ITEM_BOTTOM)
vec3 newPos;
vec3_zero(&newPos);
@ -1049,12 +1043,14 @@ void OBSBasicPreview::CropItem(const vec2 &pos)
if (stretchFlags & ITEM_LEFT)
crop.left += int(std::round(tl.x / scale.x));
else if (stretchFlags & ITEM_RIGHT)
crop.right += int(std::round((stretchItemSize.x - br.x) / scale.x));
crop.right +=
int(std::round((stretchItemSize.x - br.x) / scale.x));
if (stretchFlags & ITEM_TOP)
crop.top += int(std::round(tl.y / scale.y));
else if (stretchFlags & ITEM_BOTTOM)
crop.bottom += int(std::round((stretchItemSize.y - br.y) / scale.y));
crop.bottom +=
int(std::round((stretchItemSize.y - br.y) / scale.y));
vec3_transform(&newPos, &newPos, &itemToScreen);
newPos.x = std::round(newPos.x);
@ -1075,7 +1071,7 @@ void OBSBasicPreview::CropItem(const vec2 &pos)
obs_sceneitem_defer_update_begin(stretchItem);
obs_sceneitem_set_crop(stretchItem, &crop);
if (boundsType == OBS_BOUNDS_NONE)
obs_sceneitem_set_pos(stretchItem, (vec2*)&newPos);
obs_sceneitem_set_pos(stretchItem, (vec2 *)&newPos);
obs_sceneitem_defer_update_end(stretchItem);
}
@ -1109,19 +1105,20 @@ void OBSBasicPreview::StretchItem(const vec2 &pos)
obs_source_t *source = obs_sceneitem_get_source(stretchItem);
vec2 baseSize;
vec2_set(&baseSize,
float(obs_source_get_width(source)),
float(obs_source_get_height(source)));
vec2_set(&baseSize, float(obs_source_get_width(source)),
float(obs_source_get_height(source)));
vec2 size;
vec2_set(&size,br. x - tl.x, br.y - tl.y);
vec2_set(&size, br.x - tl.x, br.y - tl.y);
if (boundsType != OBS_BOUNDS_NONE) {
if (shiftDown)
ClampAspect(tl, br, size, baseSize);
if (tl.x > br.x) std::swap(tl.x, br.x);
if (tl.y > br.y) std::swap(tl.y, br.y);
if (tl.x > br.x)
std::swap(tl.x, br.x);
if (tl.y > br.y)
std::swap(tl.y, br.y);
vec2_abs(&size, &size);
@ -1177,16 +1174,16 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
pos.y = std::round(pos.y);
if (stretchHandle != ItemHandle::None) {
OBSBasic *main = reinterpret_cast<OBSBasic*>(
App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(
App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
obs_sceneitem_t *group = obs_sceneitem_get_group(
scene, stretchItem);
obs_sceneitem_t *group =
obs_sceneitem_get_group(scene, stretchItem);
if (group) {
vec3 group_pos;
vec3_set(&group_pos, pos.x, pos.y, 0.0f);
vec3_transform(&group_pos, &group_pos,
&invGroupTransform);
&invGroupTransform);
pos.x = group_pos.x;
pos.y = group_pos.y;
}
@ -1230,13 +1227,13 @@ static void DrawSquareAtPos(float x, float y)
gs_matrix_translate(&pos);
gs_matrix_translate3f(-HANDLE_RADIUS, -HANDLE_RADIUS, 0.0f);
gs_matrix_scale3f(HANDLE_RADIUS*2, HANDLE_RADIUS*2, 1.0f);
gs_matrix_scale3f(HANDLE_RADIUS * 2, HANDLE_RADIUS * 2, 1.0f);
gs_draw(GS_TRISTRIP, 0, 0);
gs_matrix_pop();
}
static void DrawLine(float x1, float y1, float x2, float y2, float thickness,
vec2 scale)
vec2 scale)
{
float ySide = (y1 == y2) ? (y1 < 0.5f ? 1.0f : -1.0f) : 0.0f;
float xSide = (x1 == x2) ? (x1 < 0.5f ? 1.0f : -1.0f) : 0.0f;
@ -1245,9 +1242,9 @@ static void DrawLine(float x1, float y1, float x2, float y2, float thickness,
gs_vertex2f(x1, y1);
gs_vertex2f(x1 + (xSide * (thickness / scale.x)),
y1 + (ySide * (thickness / scale.y)));
y1 + (ySide * (thickness / scale.y)));
gs_vertex2f(x2 + (xSide * (thickness / scale.x)),
y2 + (ySide * (thickness / scale.y)));
y2 + (ySide * (thickness / scale.y)));
gs_vertex2f(x2, y2);
gs_vertex2f(x1, y1);
@ -1292,14 +1289,12 @@ static void DrawRect(float thickness, vec2 scale)
static inline bool crop_enabled(const obs_sceneitem_crop *crop)
{
return crop->left > 0 ||
crop->top > 0 ||
crop->right > 0 ||
return crop->left > 0 || crop->top > 0 || crop->right > 0 ||
crop->bottom > 0;
}
bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
obs_sceneitem_t *item, void *param)
obs_sceneitem_t *item, void *param)
{
if (obs_sceneitem_locked(item))
return true;
@ -1308,7 +1303,7 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
return true;
bool select = config_get_bool(GetGlobalConfig(), "BasicWindow",
"OverflowSelectionHidden");
"OverflowSelectionHidden");
if (!select && !obs_sceneitem_visible(item))
return true;
@ -1319,17 +1314,18 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
gs_matrix_push();
gs_matrix_mul(&mat);
obs_sceneitem_group_enum_items(item, DrawSelectedOverflow, param);
obs_sceneitem_group_enum_items(item, DrawSelectedOverflow,
param);
gs_matrix_pop();
}
bool always = config_get_bool(GetGlobalConfig(), "BasicWindow",
"OverflowAlwaysVisible");
"OverflowAlwaysVisible");
if (!always && !obs_sceneitem_selected(item))
return true;
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview*>(param);
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview *>(param);
matrix4 boxTransform;
matrix4 invBoxTransform;
@ -1343,14 +1339,13 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
{{{1.f, 1.f, 0.f}}},
};
bool visible = std::all_of(std::begin(bounds), std::end(bounds),
[&](const vec3 &b)
{
vec3 pos;
vec3_transform(&pos, &b, &boxTransform);
vec3_transform(&pos, &pos, &invBoxTransform);
return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y);
});
bool visible = std::all_of(
std::begin(bounds), std::end(bounds), [&](const vec3 &b) {
vec3 pos;
vec3_transform(&pos, &b, &boxTransform);
vec3_transform(&pos, &pos, &invBoxTransform);
return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y);
});
if (!visible)
return true;
@ -1360,9 +1355,9 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
obs_transform_info info;
obs_sceneitem_get_info(item, &info);
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_REPEAT);
gs_eparam_t *image = gs_effect_get_param_by_name(solid, "image");
gs_eparam_t *scale = gs_effect_get_param_by_name(solid, "scale");
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_REPEAT);
gs_eparam_t *image = gs_effect_get_param_by_name(solid, "image");
gs_eparam_t *scale = gs_effect_get_param_by_name(solid, "scale");
vec2 s;
vec2_set(&s, boxTransform.x.x / 96, boxTransform.y.y / 96);
@ -1389,7 +1384,7 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
}
bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
obs_sceneitem_t *item, void *param)
obs_sceneitem_t *item, void *param)
{
if (obs_sceneitem_locked(item))
return true;
@ -1407,11 +1402,11 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
gs_matrix_pop();
}
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview*>(param);
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview *>(param);
OBSBasic *main = OBSBasic::Get();
bool hovered = prev->hoveredPreviewItem == item ||
prev->hoveredListItem == item;
prev->hoveredListItem == item;
bool selected = obs_sceneitem_selected(item);
if (!selected && !hovered)
@ -1437,14 +1432,13 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
vec4_set(&green, 0.0f, 1.0f, 0.0f, 1.0f);
vec4_set(&blue, 0.0f, 0.5f, 1.0f, 1.0f);
bool visible = std::all_of(std::begin(bounds), std::end(bounds),
[&](const vec3 &b)
{
vec3 pos;
vec3_transform(&pos, &b, &boxTransform);
vec3_transform(&pos, &pos, &invBoxTransform);
return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y);
});
bool visible = std::all_of(
std::begin(bounds), std::end(bounds), [&](const vec3 &b) {
vec3 pos;
vec3_transform(&pos, &b, &boxTransform);
vec3_transform(&pos, &pos, &invBoxTransform);
return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y);
});
if (!visible)
return true;
@ -1471,17 +1465,17 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
gs_eparam_t *colParam = gs_effect_get_param_by_name(eff, "color");
if (info.bounds_type == OBS_BOUNDS_NONE && crop_enabled(&crop)) {
#define DRAW_SIDE(side, x1, y1, x2, y2) \
if (hovered && !selected) \
gs_effect_set_vec4(colParam, &blue); \
else if (crop.side > 0) \
gs_effect_set_vec4(colParam, &green); \
DrawLine(x1, y1, x2, y2, HANDLE_RADIUS / 2, boxScale); \
gs_effect_set_vec4(colParam, &red);
#define DRAW_SIDE(side, x1, y1, x2, y2) \
if (hovered && !selected) \
gs_effect_set_vec4(colParam, &blue); \
else if (crop.side > 0) \
gs_effect_set_vec4(colParam, &green); \
DrawLine(x1, y1, x2, y2, HANDLE_RADIUS / 2, boxScale); \
gs_effect_set_vec4(colParam, &red);
DRAW_SIDE(left, 0.0f, 0.0f, 0.0f, 1.0f);
DRAW_SIDE(top, 0.0f, 0.0f, 1.0f, 0.0f);
DRAW_SIDE(right, 1.0f, 0.0f, 1.0f, 1.0f);
DRAW_SIDE(left, 0.0f, 0.0f, 0.0f, 1.0f);
DRAW_SIDE(top, 0.0f, 0.0f, 1.0f, 0.0f);
DRAW_SIDE(right, 1.0f, 0.0f, 1.0f, 1.0f);
DRAW_SIDE(bottom, 0.0f, 1.0f, 1.0f, 1.0f);
#undef DRAW_SIDE
} else {
@ -1522,7 +1516,7 @@ void OBSBasicPreview::DrawOverflow()
return;
bool hidden = config_get_bool(GetGlobalConfig(), "BasicWindow",
"OverflowHidden");
"OverflowHidden");
if (hidden)
return;
@ -1535,7 +1529,7 @@ void OBSBasicPreview::DrawOverflow()
overflow = gs_texture_create_from_file(path.c_str());
}
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
@ -1558,10 +1552,10 @@ void OBSBasicPreview::DrawSceneEditing()
GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawSceneEditing");
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID);
gs_technique_t *tech = gs_effect_get_technique(solid, "Solid");
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID);
gs_technique_t *tech = gs_effect_get_technique(solid, "Solid");
vec4 color;
vec4_set(&color, 1.0f, 0.0f, 0.0f, 1.0f);
@ -1592,13 +1586,16 @@ void OBSBasicPreview::ResetScrollingOffset()
vec2_zero(&scrollingOffset);
}
void OBSBasicPreview::SetScalingLevel(int32_t newScalingLevelVal) {
float newScalingAmountVal = pow(ZOOM_SENSITIVITY, float(newScalingLevelVal));
void OBSBasicPreview::SetScalingLevel(int32_t newScalingLevelVal)
{
float newScalingAmountVal =
pow(ZOOM_SENSITIVITY, float(newScalingLevelVal));
scalingLevel = newScalingLevelVal;
SetScalingAmount(newScalingAmountVal);
}
void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal) {
void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal)
{
scrollingOffset.x *= newScalingAmountVal / scalingAmount;
scrollingOffset.y *= newScalingAmountVal / scalingAmount;
scalingAmount = newScalingAmountVal;

View File

@ -9,23 +9,23 @@
class OBSBasic;
class QMouseEvent;
#define ITEM_LEFT (1<<0)
#define ITEM_RIGHT (1<<1)
#define ITEM_TOP (1<<2)
#define ITEM_BOTTOM (1<<3)
#define ITEM_LEFT (1 << 0)
#define ITEM_RIGHT (1 << 1)
#define ITEM_TOP (1 << 2)
#define ITEM_BOTTOM (1 << 3)
#define ZOOM_SENSITIVITY 1.125f
enum class ItemHandle : uint32_t {
None = 0,
TopLeft = ITEM_TOP | ITEM_LEFT,
TopCenter = ITEM_TOP,
TopRight = ITEM_TOP | ITEM_RIGHT,
CenterLeft = ITEM_LEFT,
CenterRight = ITEM_RIGHT,
BottomLeft = ITEM_BOTTOM | ITEM_LEFT,
None = 0,
TopLeft = ITEM_TOP | ITEM_LEFT,
TopCenter = ITEM_TOP,
TopRight = ITEM_TOP | ITEM_RIGHT,
CenterLeft = ITEM_LEFT,
CenterRight = ITEM_RIGHT,
BottomLeft = ITEM_BOTTOM | ITEM_LEFT,
BottomCenter = ITEM_BOTTOM,
BottomRight = ITEM_BOTTOM | ITEM_RIGHT
BottomRight = ITEM_BOTTOM | ITEM_RIGHT,
};
class OBSBasicPreview : public OBSQTDisplay {
@ -35,40 +35,40 @@ class OBSBasicPreview : public OBSQTDisplay {
private:
obs_sceneitem_crop startCrop;
vec2 startItemPos;
vec2 cropSize;
vec2 startItemPos;
vec2 cropSize;
OBSSceneItem stretchGroup;
OBSSceneItem stretchItem;
ItemHandle stretchHandle = ItemHandle::None;
vec2 stretchItemSize;
matrix4 screenToItem;
matrix4 itemToScreen;
matrix4 invGroupTransform;
ItemHandle stretchHandle = ItemHandle::None;
vec2 stretchItemSize;
matrix4 screenToItem;
matrix4 itemToScreen;
matrix4 invGroupTransform;
gs_texture_t *overflow = nullptr;
vec2 startPos;
vec2 lastMoveOffset;
vec2 scrollingFrom;
vec2 scrollingOffset;
bool mouseDown = false;
bool mouseMoved = false;
bool mouseOverItems = false;
bool cropping = false;
bool locked = false;
bool scrollMode = false;
bool fixedScaling = false;
int32_t scalingLevel = 0;
float scalingAmount = 1.0f;
vec2 startPos;
vec2 lastMoveOffset;
vec2 scrollingFrom;
vec2 scrollingOffset;
bool mouseDown = false;
bool mouseMoved = false;
bool mouseOverItems = false;
bool cropping = false;
bool locked = false;
bool scrollMode = false;
bool fixedScaling = false;
int32_t scalingLevel = 0;
float scalingAmount = 1.0f;
obs_sceneitem_t *hoveredPreviewItem = nullptr;
obs_sceneitem_t *hoveredListItem = nullptr;
obs_sceneitem_t *hoveredListItem = nullptr;
static vec2 GetMouseEventPos(QMouseEvent *event);
static bool DrawSelectedOverflow(obs_scene_t *scene,
obs_sceneitem_t *item, void *param);
obs_sceneitem_t *item, void *param);
static bool DrawSelectedItem(obs_scene_t *scene, obs_sceneitem_t *item,
void *param);
void *param);
static OBSSceneItem GetItemAtPos(const vec2 &pos, bool selectBelow);
static bool SelectedAtPos(const vec2 &pos);
@ -110,11 +110,14 @@ public:
void DrawOverflow();
void DrawSceneEditing();
inline void SetLocked(bool newLockedVal) {locked = newLockedVal;}
inline void ToggleLocked() {locked = !locked;}
inline bool Locked() const {return locked;}
inline void SetLocked(bool newLockedVal) { locked = newLockedVal; }
inline void ToggleLocked() { locked = !locked; }
inline bool Locked() const { return locked; }
inline void SetFixedScaling(bool newFixedScalingVal) { fixedScaling = newFixedScalingVal; }
inline void SetFixedScaling(bool newFixedScalingVal)
{
fixedScaling = newFixedScalingVal;
}
inline bool IsFixedScaling() const { return fixedScaling; }
void SetScalingLevel(int32_t newScalingLevelVal);
@ -123,14 +126,17 @@ public:
inline float GetScalingAmount() const { return scalingAmount; }
void ResetScrollingOffset();
inline void SetScrollingOffset(float x, float y) {vec2_set(&scrollingOffset, x, y);}
inline float GetScrollX() const {return scrollingOffset.x;}
inline float GetScrollY() const {return scrollingOffset.y;}
inline void SetScrollingOffset(float x, float y)
{
vec2_set(&scrollingOffset, x, y);
}
inline float GetScrollX() const { return scrollingOffset.x; }
inline float GetScrollY() const { return scrollingOffset.y; }
/* use libobs allocator for alignment because the matrices itemToScreen
* and screenToItem may contain SSE data, which will cause SSE
* instructions to crash if the data is not aligned to at least a 16
* byte boundary. */
static inline void* operator new(size_t size) {return bmalloc(size);}
static inline void operator delete(void* ptr) {bfree(ptr);}
static inline void *operator new(size_t size) { return bmalloc(size); }
static inline void operator delete(void *ptr) { bfree(ptr); }
};

View File

@ -32,36 +32,34 @@ using namespace std;
static void CreateTransitionScene(OBSSource scene, char *text, uint32_t color);
OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
: QDialog (parent),
preview (new OBSQTDisplay(this)),
main (qobject_cast<OBSBasic*>(parent)),
acceptClicked (false),
source (source_),
removedSignal (obs_source_get_signal_handler(source),
"remove", OBSBasicProperties::SourceRemoved,
this),
renamedSignal (obs_source_get_signal_handler(source),
"rename", OBSBasicProperties::SourceRenamed,
this),
oldSettings (obs_data_create()),
buttonBox (new QDialogButtonBox(this))
: QDialog(parent),
preview(new OBSQTDisplay(this)),
main(qobject_cast<OBSBasic *>(parent)),
acceptClicked(false),
source(source_),
removedSignal(obs_source_get_signal_handler(source), "remove",
OBSBasicProperties::SourceRemoved, this),
renamedSignal(obs_source_get_signal_handler(source), "rename",
OBSBasicProperties::SourceRenamed, this),
oldSettings(obs_data_create()),
buttonBox(new QDialogButtonBox(this))
{
int cx = (int)config_get_int(App()->GlobalConfig(), "PropertiesWindow",
"cx");
"cx");
int cy = (int)config_get_int(App()->GlobalConfig(), "PropertiesWindow",
"cy");
"cy");
enum obs_source_type type = obs_source_get_type(source);
buttonBox->setObjectName(QStringLiteral("buttonBox"));
buttonBox->setStandardButtons(QDialogButtonBox::Ok |
QDialogButtonBox::Cancel |
QDialogButtonBox::RestoreDefaults);
QDialogButtonBox::Cancel |
QDialogButtonBox::RestoreDefaults);
buttonBox->button(QDialogButtonBox::Ok)->setText(QTStr("OK"));
buttonBox->button(QDialogButtonBox::Cancel)->setText(QTStr("Cancel"));
buttonBox->button(QDialogButtonBox::RestoreDefaults)->
setText(QTStr("Defaults"));
buttonBox->button(QDialogButtonBox::RestoreDefaults)
->setText(QTStr("Defaults"));
if (cx > 400 && cy > 400)
resize(cx, cy);
@ -79,14 +77,15 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
obs_data_apply(oldSettings, settings);
obs_data_release(settings);
view = new OBSPropertiesView(settings, source,
(PropertiesReloadCallback)obs_source_properties,
(PropertiesUpdateCallback)obs_source_update);
view = new OBSPropertiesView(
settings, source,
(PropertiesReloadCallback)obs_source_properties,
(PropertiesUpdateCallback)obs_source_update);
view->setMinimumHeight(150);
preview->setMinimumSize(20, 150);
preview->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding));
preview->setSizePolicy(
QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
// Create a QSplitter to keep a unified workflow here.
windowSplitter = new QSplitter(Qt::Orientation::Vertical, this);
@ -102,8 +101,8 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
if (type == OBS_SOURCE_TYPE_TRANSITION) {
AddPreviewButton();
connect(view, SIGNAL(PropertiesRefreshed()),
this, SLOT(AddPreviewButton()));
connect(view, SIGNAL(PropertiesRefreshed()), this,
SLOT(AddPreviewButton()));
}
layout()->addWidget(buttonBox);
@ -118,35 +117,35 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
obs_source_inc_showing(source);
updatePropertiesSignal.Connect(obs_source_get_signal_handler(source),
"update_properties",
OBSBasicProperties::UpdateProperties,
this);
"update_properties",
OBSBasicProperties::UpdateProperties,
this);
auto addDrawCallback = [this] ()
{
auto addDrawCallback = [this]() {
obs_display_add_draw_callback(preview->GetDisplay(),
OBSBasicProperties::DrawPreview, this);
OBSBasicProperties::DrawPreview,
this);
};
auto addTransitionDrawCallback = [this] ()
{
obs_display_add_draw_callback(preview->GetDisplay(),
auto addTransitionDrawCallback = [this]() {
obs_display_add_draw_callback(
preview->GetDisplay(),
OBSBasicProperties::DrawTransitionPreview, this);
};
uint32_t caps = obs_source_get_output_flags(source);
bool drawable_type = type == OBS_SOURCE_TYPE_INPUT ||
type == OBS_SOURCE_TYPE_SCENE;
type == OBS_SOURCE_TYPE_SCENE;
bool drawable_preview = (caps & OBS_SOURCE_VIDEO) != 0;
if (drawable_preview && drawable_type) {
preview->show();
connect(preview.data(), &OBSQTDisplay::DisplayCreated,
addDrawCallback);
addDrawCallback);
} else if (type == OBS_SOURCE_TYPE_TRANSITION) {
sourceA = obs_source_create_private("scene", "sourceA",
nullptr);
sourceB = obs_source_create_private("scene", "sourceB",
nullptr);
sourceA =
obs_source_create_private("scene", "sourceA", nullptr);
sourceB =
obs_source_create_private("scene", "sourceB", nullptr);
obs_source_release(sourceA);
obs_source_release(sourceB);
@ -166,7 +165,7 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
obs_data_t *settings = obs_source_get_settings(source);
sourceClone = obs_source_create_private(
obs_source_get_id(source), "clone", settings);
obs_source_get_id(source), "clone", settings);
obs_source_release(sourceClone);
obs_source_inc_active(sourceClone);
@ -174,8 +173,7 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
obs_data_release(settings);
auto updateCallback = [=]()
{
auto updateCallback = [=]() {
obs_data_t *settings = obs_source_get_settings(source);
obs_source_update(sourceClone, settings);
@ -210,15 +208,14 @@ OBSBasicProperties::~OBSBasicProperties()
void OBSBasicProperties::AddPreviewButton()
{
QPushButton *playButton = new QPushButton(
QTStr("PreviewTransition"), this);
QPushButton *playButton =
new QPushButton(QTStr("PreviewTransition"), this);
VScrollArea *area = view;
area->widget()->layout()->addWidget(playButton);
playButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
auto play = [=] ()
{
auto play = [=]() {
OBSSource start;
OBSSource end;
@ -231,9 +228,8 @@ void OBSBasicProperties::AddPreviewButton()
}
obs_transition_set(sourceClone, start);
obs_transition_start(sourceClone,
OBS_TRANSITION_MODE_AUTO,
main->GetTransitionDuration(), end);
obs_transition_start(sourceClone, OBS_TRANSITION_MODE_AUTO,
main->GetTransitionDuration(), end);
direction = !direction;
start = nullptr;
@ -273,8 +269,8 @@ static obs_source_t *CreateLabel(const char *name, size_t h)
const char *text_source_id = "text_ft2_source";
#endif
obs_source_t *txtSource = obs_source_create_private(text_source_id,
name, settings);
obs_source_t *txtSource =
obs_source_create_private(text_source_id, name, settings);
obs_data_release(font);
obs_data_release(settings);
@ -289,21 +285,21 @@ static void CreateTransitionScene(OBSSource scene, char *text, uint32_t color)
obs_data_set_int(settings, "height", obs_source_get_height(scene));
obs_data_set_int(settings, "color", color);
obs_source_t *colorBG = obs_source_create_private("color_source",
"background", settings);
obs_source_t *colorBG = obs_source_create_private(
"color_source", "background", settings);
obs_scene_add(obs_scene_from_source(scene), colorBG);
obs_source_t *label = CreateLabel(text, obs_source_get_height(scene));
obs_sceneitem_t *item = obs_scene_add(obs_scene_from_source(scene),
label);
obs_sceneitem_t *item =
obs_scene_add(obs_scene_from_source(scene), label);
vec2 size;
vec2_set(&size, obs_source_get_width(scene),
#ifdef _WIN32
obs_source_get_height(scene));
obs_source_get_height(scene));
#else
obs_source_get_height(scene) * 0.8);
obs_source_get_height(scene) * 0.8);
#endif
obs_sceneitem_set_bounds(item, &size);
@ -316,8 +312,8 @@ static void CreateTransitionScene(OBSSource scene, char *text, uint32_t color)
void OBSBasicProperties::SourceRemoved(void *data, calldata_t *params)
{
QMetaObject::invokeMethod(static_cast<OBSBasicProperties*>(data),
"close");
QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data),
"close");
UNUSED_PARAMETER(params);
}
@ -327,14 +323,14 @@ void OBSBasicProperties::SourceRenamed(void *data, calldata_t *params)
const char *name = calldata_string(params, "new_name");
QString title = QTStr("Basic.PropertiesWindow").arg(QT_UTF8(name));
QMetaObject::invokeMethod(static_cast<OBSBasicProperties*>(data),
"setWindowTitle", Q_ARG(QString, title));
QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data),
"setWindowTitle", Q_ARG(QString, title));
}
void OBSBasicProperties::UpdateProperties(void *data, calldata_t *)
{
QMetaObject::invokeMethod(static_cast<OBSBasicProperties*>(data)->view,
"ReloadProperties");
QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data)->view,
"ReloadProperties");
}
void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
@ -374,7 +370,7 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy)
{
OBSBasicProperties *window = static_cast<OBSBasicProperties*>(data);
OBSBasicProperties *window = static_cast<OBSBasicProperties *>(data);
if (!window->source)
return;
@ -382,8 +378,8 @@ void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy)
uint32_t sourceCX = max(obs_source_get_width(window->source), 1u);
uint32_t sourceCY = max(obs_source_get_height(window->source), 1u);
int x, y;
int newCX, newCY;
int x, y;
int newCX, newCY;
float scale;
GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale);
@ -393,8 +389,7 @@ void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy)
gs_viewport_push();
gs_projection_push();
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY),
-100.0f, 100.0f);
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), -100.0f, 100.0f);
gs_set_viewport(x, y, newCX, newCY);
obs_source_video_render(window->source);
@ -404,9 +399,9 @@ void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy)
}
void OBSBasicProperties::DrawTransitionPreview(void *data, uint32_t cx,
uint32_t cy)
uint32_t cy)
{
OBSBasicProperties *window = static_cast<OBSBasicProperties*>(data);
OBSBasicProperties *window = static_cast<OBSBasicProperties *>(data);
if (!window->source)
return;
@ -414,8 +409,8 @@ void OBSBasicProperties::DrawTransitionPreview(void *data, uint32_t cx,
uint32_t sourceCX = max(obs_source_get_width(window->source), 1u);
uint32_t sourceCY = max(obs_source_get_height(window->source), 1u);
int x, y;
int newCX, newCY;
int x, y;
int newCX, newCY;
float scale;
GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale);
@ -425,8 +420,7 @@ void OBSBasicProperties::DrawTransitionPreview(void *data, uint32_t cx,
gs_viewport_push();
gs_projection_push();
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY),
-100.0f, 100.0f);
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), -100.0f, 100.0f);
gs_set_viewport(x, y, newCX, newCY);
obs_source_video_render(window->sourceClone);
@ -438,13 +432,14 @@ void OBSBasicProperties::DrawTransitionPreview(void *data, uint32_t cx,
void OBSBasicProperties::Cleanup()
{
config_set_int(App()->GlobalConfig(), "PropertiesWindow", "cx",
width());
width());
config_set_int(App()->GlobalConfig(), "PropertiesWindow", "cy",
height());
height());
obs_display_remove_draw_callback(preview->GetDisplay(),
OBSBasicProperties::DrawPreview, this);
obs_display_remove_draw_callback(preview->GetDisplay(),
OBSBasicProperties::DrawPreview, this);
obs_display_remove_draw_callback(
preview->GetDisplay(),
OBSBasicProperties::DrawTransitionPreview, this);
}
@ -497,11 +492,10 @@ bool OBSBasicProperties::ConfirmQuit()
{
QMessageBox::StandardButton button;
button = OBSMessageBox::question(this,
QTStr("Basic.PropertiesWindow.ConfirmTitle"),
QTStr("Basic.PropertiesWindow.Confirm"),
QMessageBox::Save | QMessageBox::Discard |
QMessageBox::Cancel);
button = OBSMessageBox::question(
this, QTStr("Basic.PropertiesWindow.ConfirmTitle"),
QTStr("Basic.PropertiesWindow.Confirm"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
switch (button) {
case QMessageBox::Save:

Some files were not shown because too many files have changed in this diff Show More