frontend: Split main application implementation into single files
This commit is contained in:
parent
bcc6880183
commit
2be464a21f
1165
frontend/OBSApp.cpp
1165
frontend/OBSApp.cpp
File diff suppressed because it is too large
Load Diff
@ -17,63 +17,30 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTranslator>
|
||||
#include <QPointer>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <utility/OBSTheme.hpp>
|
||||
#include <widgets/OBSMainWindow.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <QSocketNotifier>
|
||||
#else
|
||||
#include <QSessionManager>
|
||||
#endif
|
||||
#include <obs.hpp>
|
||||
#include <util/lexer.h>
|
||||
#include <util/profiler.h>
|
||||
#include <util/util.hpp>
|
||||
#include <util/platform.h>
|
||||
#include <obs-frontend-api.h>
|
||||
#include <util/platform.h>
|
||||
#include <util/profiler.hpp>
|
||||
#include <util/util.hpp>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPalette>
|
||||
#include <QPointer>
|
||||
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <filesystem>
|
||||
|
||||
#include "window-main.hpp"
|
||||
#include "obs-app-theming.hpp"
|
||||
|
||||
std::string CurrentTimeString();
|
||||
std::string CurrentDateTimeString();
|
||||
std::string GenerateTimeDateFilename(const char *extension, bool noSpace = false);
|
||||
std::string GenerateSpecifiedFilename(const char *extension, bool noSpace, const char *format);
|
||||
std::string GetFormatString(const char *format, const char *prefix, const char *suffix);
|
||||
std::string GetFormatExt(const char *container);
|
||||
std::string GetOutputFilename(const char *path, const char *container, bool noSpace, bool overwrite,
|
||||
const char *format);
|
||||
QObject *CreateShortcutFilter();
|
||||
|
||||
struct BaseLexer {
|
||||
lexer lex;
|
||||
|
||||
public:
|
||||
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 QString translate(const char *context, const char *sourceText, const char *disambiguation,
|
||||
int n) const override;
|
||||
};
|
||||
|
||||
typedef std::function<void()> VoidFunc;
|
||||
|
||||
Q_DECLARE_METATYPE(VoidFunc)
|
||||
|
||||
class QFileSystemWatcher;
|
||||
class QSocketNotifier;
|
||||
|
||||
struct UpdateBranch {
|
||||
QString name;
|
||||
QString display_name;
|
||||
@ -233,9 +200,6 @@ signals:
|
||||
int GetAppConfigPath(char *path, size_t size, const char *name);
|
||||
char *GetAppConfigPathPtr(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);
|
||||
@ -251,30 +215,23 @@ inline QString QTStr(const char *lookupVal)
|
||||
return QString::fromUtf8(Str(lookupVal));
|
||||
}
|
||||
|
||||
int GetProgramDataPath(char *path, size_t size, const char *name);
|
||||
char *GetProgramDataPathPtr(const char *name);
|
||||
|
||||
bool GetFileSafeName(const char *name, std::string &file);
|
||||
bool GetClosestUnusedFileName(std::string &path, const char *extension);
|
||||
bool GetUnusedSceneCollectionFile(std::string &name, std::string &file);
|
||||
|
||||
bool WindowPositionValid(QRect rect);
|
||||
|
||||
extern bool portable_mode;
|
||||
extern bool steam;
|
||||
extern bool safe_mode;
|
||||
extern bool disable_3p_plugins;
|
||||
|
||||
extern bool opt_start_streaming;
|
||||
extern bool opt_start_recording;
|
||||
extern bool opt_start_replaybuffer;
|
||||
extern bool opt_start_virtualcam;
|
||||
extern bool opt_minimize_tray;
|
||||
extern bool opt_studio_mode;
|
||||
extern bool opt_allow_opengl;
|
||||
extern bool opt_always_on_top;
|
||||
extern std::string opt_starting_scene;
|
||||
extern bool restart;
|
||||
extern bool restart_safe;
|
||||
|
||||
#ifdef _WIN32
|
||||
extern "C" void install_dll_blocklist_hook(void);
|
||||
extern "C" void log_blocked_dlls(void);
|
||||
#endif
|
||||
|
||||
std::string CurrentDateTimeString();
|
||||
std::string GetFormatString(const char *format, const char *prefix, const char *suffix);
|
||||
std::string GenerateTimeDateFilename(const char *extension, bool noSpace = false);
|
||||
std::string GetFormatExt(const char *container);
|
||||
std::string GetOutputFilename(const char *path, const char *container, bool noSpace, bool overwrite,
|
||||
const char *format);
|
||||
QObject *CreateShortcutFilter();
|
||||
|
@ -15,25 +15,23 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
#include <cinttypes>
|
||||
#include "OBSApp.hpp"
|
||||
|
||||
#include <utility/OBSProxyStyle.hpp>
|
||||
#include <utility/OBSThemeVariable.hpp>
|
||||
#include <utility/platform.hpp>
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <ui-config.h>
|
||||
#include <util/cf-parser.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
#include <QMetaEnum>
|
||||
#include <QDirIterator>
|
||||
#include <QGuiApplication>
|
||||
#include <QFile>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QMetaEnum>
|
||||
#include <QRandomGenerator>
|
||||
|
||||
#include "qt-wrappers.hpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "obs-app-theming.hpp"
|
||||
#include "obs-proxy-style.hpp"
|
||||
#include "platform.hpp"
|
||||
|
||||
#include "ui-config.h"
|
||||
#include <QTimer>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,29 +1,28 @@
|
||||
#include <obs-frontend-internal.hpp>
|
||||
#include <qt-wrappers.hpp>
|
||||
#include "obs-app.hpp"
|
||||
#include "window-basic-main.hpp"
|
||||
#include "window-basic-main-outputs.hpp"
|
||||
/******************************************************************************
|
||||
Copyright (C) 2024 by Patrick Heyer <opensource@patrickheyer.com>
|
||||
|
||||
#include <functional>
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <obs-frontend-internal.hpp>
|
||||
|
||||
class OBSBasic;
|
||||
|
||||
using namespace std;
|
||||
|
||||
Q_DECLARE_METATYPE(OBSScene);
|
||||
Q_DECLARE_METATYPE(OBSSource);
|
||||
|
||||
template<typename T> static T GetOBSRef(QListWidgetItem *item)
|
||||
{
|
||||
return item->data(static_cast<int>(QtDataRole::OBSRef)).value<T>();
|
||||
}
|
||||
|
||||
extern volatile bool streaming_active;
|
||||
extern volatile bool recording_active;
|
||||
extern volatile bool recording_paused;
|
||||
extern volatile bool replaybuf_active;
|
||||
extern volatile bool virtualcam_active;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
template<typename T> struct OBSStudioCallback {
|
||||
T callback;
|
||||
void *private_data;
|
||||
@ -31,18 +30,6 @@ template<typename T> struct OBSStudioCallback {
|
||||
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)
|
||||
{
|
||||
for (size_t i = 0; i < callbacks.size(); i++) {
|
||||
OBSStudioCallback<T> curCB = callbacks[i];
|
||||
if (curCB.callback == callback && curCB.private_data == private_data)
|
||||
return i;
|
||||
}
|
||||
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
struct OBSStudioAPI : obs_frontend_callbacks {
|
||||
OBSBasic *main;
|
||||
vector<OBSStudioCallback<obs_frontend_event_cb>> callbacks;
|
||||
@ -51,586 +38,199 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
||||
|
||||
inline OBSStudioAPI(OBSBasic *main_) : main(main_) {}
|
||||
|
||||
void *obs_frontend_get_main_window(void) override { return (void *)main; }
|
||||
|
||||
void *obs_frontend_get_main_window_handle(void) override { return (void *)main->winId(); }
|
||||
|
||||
void *obs_frontend_get_system_tray(void) override { return (void *)main->trayIcon.data(); }
|
||||
|
||||
void obs_frontend_get_scenes(struct obs_frontend_source_list *sources) override
|
||||
{
|
||||
for (int i = 0; i < main->ui->scenes->count(); i++) {
|
||||
QListWidgetItem *item = main->ui->scenes->item(i);
|
||||
OBSScene scene = GetOBSRef<OBSScene>(item);
|
||||
obs_source_t *source = obs_scene_get_source(scene);
|
||||
|
||||
if (obs_source_get_ref(source) != nullptr)
|
||||
da_push_back(sources->sources, &source);
|
||||
}
|
||||
}
|
||||
|
||||
obs_source_t *obs_frontend_get_current_scene(void) override
|
||||
{
|
||||
if (main->IsPreviewProgramMode()) {
|
||||
return obs_weak_source_get_source(main->programScene);
|
||||
} else {
|
||||
OBSSource source = main->GetCurrentSceneSource();
|
||||
return obs_source_get_ref(source);
|
||||
}
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_scene(obs_source_t *scene) override
|
||||
{
|
||||
if (main->IsPreviewProgramMode()) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
void obs_frontend_get_transitions(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>();
|
||||
|
||||
if (!tr)
|
||||
continue;
|
||||
|
||||
if (obs_source_get_ref(tr) != nullptr)
|
||||
da_push_back(sources->sources, &tr);
|
||||
}
|
||||
}
|
||||
|
||||
obs_source_t *obs_frontend_get_current_transition(void) override
|
||||
{
|
||||
OBSSource tr = main->GetCurrentTransition();
|
||||
return obs_source_get_ref(tr);
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_transition(obs_source_t *transition) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "SetTransition", Q_ARG(OBSSource, OBSSource(transition)));
|
||||
}
|
||||
|
||||
int obs_frontend_get_transition_duration(void) override { return main->ui->transitionDuration->value(); }
|
||||
|
||||
void obs_frontend_set_transition_duration(int duration) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main->ui->transitionDuration, "setValue", Q_ARG(int, duration));
|
||||
}
|
||||
|
||||
void obs_frontend_release_tbar(void) override { QMetaObject::invokeMethod(main, "TBarReleased"); }
|
||||
|
||||
void obs_frontend_set_tbar_position(int position) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "TBarChanged", Q_ARG(int, position));
|
||||
}
|
||||
|
||||
int obs_frontend_get_tbar_position(void) override { return main->tBar->value(); }
|
||||
|
||||
void obs_frontend_get_scene_collections(std::vector<std::string> &strings) override
|
||||
{
|
||||
for (auto &[collectionName, collection] : main->GetSceneCollectionCache()) {
|
||||
strings.emplace_back(collectionName);
|
||||
}
|
||||
}
|
||||
|
||||
char *obs_frontend_get_current_scene_collection(void) override
|
||||
{
|
||||
const OBSSceneCollection ¤tCollection = main->GetCurrentSceneCollection();
|
||||
return bstrdup(currentCollection.name.c_str());
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_scene_collection(const char *collection) override
|
||||
{
|
||||
QList<QAction *> menuActions = main->ui->sceneCollectionMenu->actions();
|
||||
QString qstrCollection = QT_UTF8(collection);
|
||||
|
||||
for (int i = 0; i < menuActions.count(); i++) {
|
||||
QAction *action = menuActions[i];
|
||||
QVariant v = action->property("file_name");
|
||||
|
||||
if (v.typeName() != nullptr) {
|
||||
if (action->text() == qstrCollection) {
|
||||
action->trigger();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool obs_frontend_add_scene_collection(const char *name) override
|
||||
{
|
||||
bool success = false;
|
||||
QMetaObject::invokeMethod(main, "CreateNewSceneCollection", WaitConnection(),
|
||||
Q_RETURN_ARG(bool, success), Q_ARG(QString, QT_UTF8(name)));
|
||||
return success;
|
||||
}
|
||||
|
||||
void obs_frontend_get_profiles(std::vector<std::string> &strings) override
|
||||
{
|
||||
const OBSProfileCache &profiles = main->GetProfileCache();
|
||||
|
||||
for (auto &[profileName, profile] : profiles) {
|
||||
strings.emplace_back(profileName);
|
||||
}
|
||||
}
|
||||
|
||||
char *obs_frontend_get_current_profile(void) override
|
||||
{
|
||||
const OBSProfile &profile = main->GetCurrentProfile();
|
||||
return bstrdup(profile.name.c_str());
|
||||
}
|
||||
|
||||
char *obs_frontend_get_current_profile_path(void) override
|
||||
{
|
||||
const OBSProfile &profile = main->GetCurrentProfile();
|
||||
|
||||
return bstrdup(profile.path.u8string().c_str());
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_profile(const char *profile) override
|
||||
{
|
||||
QList<QAction *> menuActions = main->ui->profileMenu->actions();
|
||||
QString qstrProfile = QT_UTF8(profile);
|
||||
|
||||
for (int i = 0; i < menuActions.count(); i++) {
|
||||
QAction *action = menuActions[i];
|
||||
QVariant v = action->property("file_name");
|
||||
|
||||
if (v.typeName() != nullptr) {
|
||||
if (action->text() == qstrProfile) {
|
||||
action->trigger();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void obs_frontend_create_profile(const char *name) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "CreateNewProfile", Q_ARG(QString, name));
|
||||
}
|
||||
|
||||
void obs_frontend_duplicate_profile(const char *name) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "CreateDuplicateProfile", Q_ARG(QString, name));
|
||||
}
|
||||
|
||||
void obs_frontend_delete_profile(const char *profile) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "DeleteProfile", Q_ARG(QString, profile));
|
||||
}
|
||||
|
||||
void obs_frontend_streaming_start(void) override { QMetaObject::invokeMethod(main, "StartStreaming"); }
|
||||
|
||||
void obs_frontend_streaming_stop(void) override { QMetaObject::invokeMethod(main, "StopStreaming"); }
|
||||
|
||||
bool obs_frontend_streaming_active(void) override { return os_atomic_load_bool(&streaming_active); }
|
||||
|
||||
void obs_frontend_recording_start(void) override { QMetaObject::invokeMethod(main, "StartRecording"); }
|
||||
|
||||
void obs_frontend_recording_stop(void) override { QMetaObject::invokeMethod(main, "StopRecording"); }
|
||||
|
||||
bool obs_frontend_recording_active(void) override { return os_atomic_load_bool(&recording_active); }
|
||||
|
||||
void obs_frontend_recording_pause(bool pause) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, pause ? "PauseRecording" : "UnpauseRecording");
|
||||
}
|
||||
|
||||
bool obs_frontend_recording_paused(void) override { return os_atomic_load_bool(&recording_paused); }
|
||||
|
||||
bool obs_frontend_recording_split_file(void) override
|
||||
{
|
||||
if (os_atomic_load_bool(&recording_active) && !os_atomic_load_bool(&recording_paused)) {
|
||||
proc_handler_t *ph = obs_output_get_proc_handler(main->outputHandler->fileOutput);
|
||||
uint8_t stack[128];
|
||||
calldata cd;
|
||||
calldata_init_fixed(&cd, stack, sizeof(stack));
|
||||
proc_handler_call(ph, "split_file", &cd);
|
||||
bool result = calldata_bool(&cd, "split_file_enabled");
|
||||
return result;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool obs_frontend_recording_add_chapter(const char *name) override
|
||||
{
|
||||
if (!os_atomic_load_bool(&recording_active) || os_atomic_load_bool(&recording_paused))
|
||||
return false;
|
||||
|
||||
proc_handler_t *ph = obs_output_get_proc_handler(main->outputHandler->fileOutput);
|
||||
|
||||
calldata cd;
|
||||
calldata_init(&cd);
|
||||
calldata_set_string(&cd, "chapter_name", name);
|
||||
bool result = proc_handler_call(ph, "add_chapter", &cd);
|
||||
calldata_free(&cd);
|
||||
return result;
|
||||
}
|
||||
|
||||
void obs_frontend_replay_buffer_start(void) override { QMetaObject::invokeMethod(main, "StartReplayBuffer"); }
|
||||
|
||||
void obs_frontend_replay_buffer_save(void) override { QMetaObject::invokeMethod(main, "ReplayBufferSave"); }
|
||||
|
||||
void obs_frontend_replay_buffer_stop(void) override { QMetaObject::invokeMethod(main, "StopReplayBuffer"); }
|
||||
|
||||
bool obs_frontend_replay_buffer_active(void) override { return os_atomic_load_bool(&replaybuf_active); }
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void obs_frontend_add_tools_menu_item(const char *name, obs_frontend_cb callback, void *private_data) override
|
||||
{
|
||||
main->ui->menuTools->setEnabled(true);
|
||||
|
||||
auto func = [private_data, callback]() {
|
||||
callback(private_data);
|
||||
};
|
||||
|
||||
QAction *action = main->ui->menuTools->addAction(QT_UTF8(name));
|
||||
QObject::connect(action, &QAction::triggered, func);
|
||||
}
|
||||
|
||||
void *obs_frontend_add_dock(void *dock) override
|
||||
{
|
||||
QDockWidget *d = reinterpret_cast<QDockWidget *>(dock);
|
||||
|
||||
QString name = d->objectName();
|
||||
if (name.isEmpty() || main->IsDockObjectNameUsed(name)) {
|
||||
blog(LOG_WARNING, "The object name of the added dock is empty or already used,"
|
||||
" a temporary one will be set to avoid conflicts");
|
||||
|
||||
char *uuid = os_generate_uuid();
|
||||
name = QT_UTF8(uuid);
|
||||
bfree(uuid);
|
||||
name.append("_oldExtraDock");
|
||||
|
||||
d->setObjectName(name);
|
||||
}
|
||||
|
||||
return (void *)main->AddDockWidget(d);
|
||||
}
|
||||
|
||||
bool obs_frontend_add_dock_by_id(const char *id, const char *title, void *widget) override
|
||||
{
|
||||
if (main->IsDockObjectNameUsed(QT_UTF8(id))) {
|
||||
blog(LOG_WARNING,
|
||||
"Dock id '%s' already used! "
|
||||
"Duplicate library?",
|
||||
id);
|
||||
return false;
|
||||
}
|
||||
|
||||
OBSDock *dock = new OBSDock(main);
|
||||
dock->setWidget((QWidget *)widget);
|
||||
dock->setWindowTitle(QT_UTF8(title));
|
||||
dock->setObjectName(QT_UTF8(id));
|
||||
|
||||
main->AddDockWidget(dock, Qt::RightDockWidgetArea);
|
||||
|
||||
dock->setVisible(false);
|
||||
dock->setFloating(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void obs_frontend_remove_dock(const char *id) override { main->RemoveDockWidget(QT_UTF8(id)); }
|
||||
|
||||
bool obs_frontend_add_custom_qdock(const char *id, void *dock) override
|
||||
{
|
||||
if (main->IsDockObjectNameUsed(QT_UTF8(id))) {
|
||||
blog(LOG_WARNING,
|
||||
"Dock id '%s' already used! "
|
||||
"Duplicate library?",
|
||||
id);
|
||||
return false;
|
||||
}
|
||||
|
||||
QDockWidget *d = reinterpret_cast<QDockWidget *>(dock);
|
||||
d->setObjectName(QT_UTF8(id));
|
||||
|
||||
main->AddCustomDockWidget(d);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void obs_frontend_add_event_callback(obs_frontend_event_cb callback, void *private_data) override
|
||||
{
|
||||
size_t idx = GetCallbackIdx(callbacks, callback, private_data);
|
||||
if (idx == (size_t)-1)
|
||||
callbacks.emplace_back(callback, private_data);
|
||||
}
|
||||
|
||||
void obs_frontend_remove_event_callback(obs_frontend_event_cb callback, void *private_data) override
|
||||
{
|
||||
size_t idx = GetCallbackIdx(callbacks, callback, private_data);
|
||||
if (idx == (size_t)-1)
|
||||
return;
|
||||
|
||||
callbacks.erase(callbacks.begin() + idx);
|
||||
}
|
||||
|
||||
obs_output_t *obs_frontend_get_streaming_output(void) override
|
||||
{
|
||||
auto multitrackVideo = main->outputHandler->multitrackVideo.get();
|
||||
auto mtvOutput = multitrackVideo ? obs_output_get_ref(multitrackVideo->StreamingOutput()) : nullptr;
|
||||
if (mtvOutput)
|
||||
return mtvOutput;
|
||||
|
||||
OBSOutput output = main->outputHandler->streamOutput.Get();
|
||||
return obs_output_get_ref(output);
|
||||
}
|
||||
|
||||
obs_output_t *obs_frontend_get_recording_output(void) override
|
||||
{
|
||||
OBSOutput out = main->outputHandler->fileOutput.Get();
|
||||
return obs_output_get_ref(out);
|
||||
}
|
||||
|
||||
obs_output_t *obs_frontend_get_replay_buffer_output(void) override
|
||||
{
|
||||
OBSOutput out = main->outputHandler->replayBuffer.Get();
|
||||
return obs_output_get_ref(out);
|
||||
}
|
||||
|
||||
config_t *obs_frontend_get_profile_config(void) override { return main->activeConfiguration; }
|
||||
|
||||
config_t *obs_frontend_get_global_config(void) override
|
||||
{
|
||||
blog(LOG_WARNING,
|
||||
"DEPRECATION: obs_frontend_get_global_config is deprecated. Read from global or user configuration explicitly instead.");
|
||||
return App()->GetAppConfig();
|
||||
}
|
||||
|
||||
config_t *obs_frontend_get_app_config(void) override { return App()->GetAppConfig(); }
|
||||
|
||||
config_t *obs_frontend_get_user_config(void) override { return App()->GetUserConfig(); }
|
||||
|
||||
void obs_frontend_open_projector(const char *type, int monitor, const char *geometry, const char *name) override
|
||||
{
|
||||
SavedProjectorInfo proj = {
|
||||
ProjectorType::Preview,
|
||||
monitor,
|
||||
geometry ? geometry : "",
|
||||
name ? name : "",
|
||||
};
|
||||
if (type) {
|
||||
if (astrcmpi(type, "Source") == 0)
|
||||
proj.type = ProjectorType::Source;
|
||||
else if (astrcmpi(type, "Scene") == 0)
|
||||
proj.type = ProjectorType::Scene;
|
||||
else if (astrcmpi(type, "StudioProgram") == 0)
|
||||
proj.type = ProjectorType::StudioProgram;
|
||||
else if (astrcmpi(type, "Multiview") == 0)
|
||||
proj.type = ProjectorType::Multiview;
|
||||
}
|
||||
QMetaObject::invokeMethod(main, "OpenSavedProjector", WaitConnection(),
|
||||
Q_ARG(SavedProjectorInfo *, &proj));
|
||||
}
|
||||
|
||||
void obs_frontend_save(void) override { main->SaveProject(); }
|
||||
|
||||
void obs_frontend_defer_save_begin(void) override { QMetaObject::invokeMethod(main, "DeferSaveBegin"); }
|
||||
|
||||
void obs_frontend_defer_save_end(void) override { QMetaObject::invokeMethod(main, "DeferSaveEnd"); }
|
||||
|
||||
void obs_frontend_add_save_callback(obs_frontend_save_cb callback, void *private_data) override
|
||||
{
|
||||
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
|
||||
{
|
||||
size_t idx = GetCallbackIdx(saveCallbacks, callback, private_data);
|
||||
if (idx == (size_t)-1)
|
||||
return;
|
||||
|
||||
saveCallbacks.erase(saveCallbacks.begin() + idx);
|
||||
}
|
||||
|
||||
void obs_frontend_add_preload_callback(obs_frontend_save_cb callback, void *private_data) override
|
||||
{
|
||||
size_t idx = GetCallbackIdx(preloadCallbacks, callback, 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
|
||||
{
|
||||
size_t idx = GetCallbackIdx(preloadCallbacks, callback, private_data);
|
||||
if (idx == (size_t)-1)
|
||||
return;
|
||||
|
||||
preloadCallbacks.erase(preloadCallbacks.begin() + idx);
|
||||
}
|
||||
|
||||
void obs_frontend_push_ui_translation(obs_frontend_translate_ui_cb translate) override
|
||||
{
|
||||
App()->PushUITranslation(translate);
|
||||
}
|
||||
|
||||
void obs_frontend_pop_ui_translation(void) override { App()->PopUITranslation(); }
|
||||
|
||||
void obs_frontend_set_streaming_service(obs_service_t *service) override { main->SetService(service); }
|
||||
|
||||
obs_service_t *obs_frontend_get_streaming_service(void) override { return main->GetService(); }
|
||||
|
||||
void obs_frontend_save_streaming_service(void) override { main->SaveService(); }
|
||||
|
||||
bool obs_frontend_preview_program_mode_active(void) override { return main->IsPreviewProgramMode(); }
|
||||
|
||||
void obs_frontend_set_preview_program_mode(bool enable) override { main->SetPreviewProgramMode(enable); }
|
||||
|
||||
void obs_frontend_preview_program_trigger_transition(void) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "TransitionClicked");
|
||||
}
|
||||
|
||||
bool obs_frontend_preview_enabled(void) override { return main->previewEnabled; }
|
||||
|
||||
void obs_frontend_set_preview_enabled(bool enable) override
|
||||
{
|
||||
if (main->previewEnabled != enable)
|
||||
main->EnablePreviewDisplay(enable);
|
||||
}
|
||||
|
||||
obs_source_t *obs_frontend_get_current_preview_scene(void) override
|
||||
{
|
||||
if (main->IsPreviewProgramMode()) {
|
||||
OBSSource source = main->GetCurrentSceneSource();
|
||||
return obs_source_get_ref(source);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
void *obs_frontend_get_main_window(void) override;
|
||||
|
||||
void obs_frontend_take_screenshot(void) override { QMetaObject::invokeMethod(main, "Screenshot"); }
|
||||
void *obs_frontend_get_main_window_handle(void) override;
|
||||
|
||||
void obs_frontend_take_source_screenshot(obs_source_t *source) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "Screenshot", Q_ARG(OBSSource, OBSSource(source)));
|
||||
}
|
||||
void *obs_frontend_get_system_tray(void) override;
|
||||
|
||||
obs_output_t *obs_frontend_get_virtualcam_output(void) override
|
||||
{
|
||||
OBSOutput output = main->outputHandler->virtualCam.Get();
|
||||
return obs_output_get_ref(output);
|
||||
}
|
||||
void obs_frontend_get_scenes(struct obs_frontend_source_list *sources) override;
|
||||
|
||||
void obs_frontend_start_virtualcam(void) override { QMetaObject::invokeMethod(main, "StartVirtualCam"); }
|
||||
obs_source_t *obs_frontend_get_current_scene(void) override;
|
||||
|
||||
void obs_frontend_stop_virtualcam(void) override { QMetaObject::invokeMethod(main, "StopVirtualCam"); }
|
||||
void obs_frontend_set_current_scene(obs_source_t *scene) override;
|
||||
|
||||
bool obs_frontend_virtualcam_active(void) override { return os_atomic_load_bool(&virtualcam_active); }
|
||||
void obs_frontend_get_transitions(struct obs_frontend_source_list *sources) override;
|
||||
|
||||
void obs_frontend_reset_video(void) override { main->ResetVideo(); }
|
||||
obs_source_t *obs_frontend_get_current_transition(void) override;
|
||||
|
||||
void obs_frontend_open_source_properties(obs_source_t *source) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "OpenProperties", Q_ARG(OBSSource, OBSSource(source)));
|
||||
}
|
||||
void obs_frontend_set_current_transition(obs_source_t *transition) override;
|
||||
|
||||
void obs_frontend_open_source_filters(obs_source_t *source) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "OpenFilters", Q_ARG(OBSSource, OBSSource(source)));
|
||||
}
|
||||
int obs_frontend_get_transition_duration(void) override;
|
||||
|
||||
void obs_frontend_open_source_interaction(obs_source_t *source) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "OpenInteraction", Q_ARG(OBSSource, OBSSource(source)));
|
||||
}
|
||||
void obs_frontend_set_transition_duration(int duration) override;
|
||||
|
||||
void obs_frontend_open_sceneitem_edit_transform(obs_sceneitem_t *item) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "OpenEditTransform", Q_ARG(OBSSceneItem, OBSSceneItem(item)));
|
||||
}
|
||||
void obs_frontend_release_tbar(void) override;
|
||||
|
||||
char *obs_frontend_get_current_record_output_path(void) override
|
||||
{
|
||||
const char *recordOutputPath = main->GetCurrentOutputPath();
|
||||
void obs_frontend_set_tbar_position(int position) override;
|
||||
|
||||
return bstrdup(recordOutputPath);
|
||||
}
|
||||
int obs_frontend_get_tbar_position(void) override;
|
||||
|
||||
const char *obs_frontend_get_locale_string(const char *string) override { return Str(string); }
|
||||
void obs_frontend_get_scene_collections(std::vector<std::string> &strings) override;
|
||||
|
||||
bool obs_frontend_is_theme_dark(void) override { return App()->IsThemeDark(); }
|
||||
char *obs_frontend_get_current_scene_collection(void) override;
|
||||
|
||||
char *obs_frontend_get_last_recording(void) override
|
||||
{
|
||||
return bstrdup(main->outputHandler->lastRecordingPath.c_str());
|
||||
}
|
||||
void obs_frontend_set_current_scene_collection(const char *collection) override;
|
||||
|
||||
char *obs_frontend_get_last_screenshot(void) override { return bstrdup(main->lastScreenshot.c_str()); }
|
||||
bool obs_frontend_add_scene_collection(const char *name) override;
|
||||
|
||||
char *obs_frontend_get_last_replay(void) override { return bstrdup(main->lastReplay.c_str()); }
|
||||
void obs_frontend_get_profiles(std::vector<std::string> &strings) override;
|
||||
|
||||
char *obs_frontend_get_current_profile(void) override;
|
||||
|
||||
char *obs_frontend_get_current_profile_path(void) override;
|
||||
|
||||
void obs_frontend_set_current_profile(const char *profile) override;
|
||||
|
||||
void obs_frontend_create_profile(const char *name) override;
|
||||
|
||||
void obs_frontend_duplicate_profile(const char *name) override;
|
||||
|
||||
void obs_frontend_delete_profile(const char *profile) override;
|
||||
|
||||
void obs_frontend_streaming_start(void) override;
|
||||
|
||||
void obs_frontend_streaming_stop(void) override;
|
||||
|
||||
bool obs_frontend_streaming_active(void) override;
|
||||
|
||||
void obs_frontend_recording_start(void) override;
|
||||
|
||||
void obs_frontend_recording_stop(void) override;
|
||||
|
||||
bool obs_frontend_recording_active(void) override;
|
||||
|
||||
void obs_frontend_recording_pause(bool pause) override;
|
||||
|
||||
bool obs_frontend_recording_paused(void) override;
|
||||
|
||||
bool obs_frontend_recording_split_file(void) override;
|
||||
|
||||
bool obs_frontend_recording_add_chapter(const char *name) override;
|
||||
|
||||
void obs_frontend_replay_buffer_start(void) override;
|
||||
|
||||
void obs_frontend_replay_buffer_save(void) override;
|
||||
|
||||
void obs_frontend_replay_buffer_stop(void) override;
|
||||
|
||||
bool obs_frontend_replay_buffer_active(void) override;
|
||||
|
||||
void *obs_frontend_add_tools_menu_qaction(const char *name) override;
|
||||
|
||||
void obs_frontend_add_tools_menu_item(const char *name, obs_frontend_cb callback, void *private_data) override;
|
||||
|
||||
void *obs_frontend_add_dock(void *dock) override;
|
||||
|
||||
bool obs_frontend_add_dock_by_id(const char *id, const char *title, void *widget) override;
|
||||
|
||||
void obs_frontend_remove_dock(const char *id) override;
|
||||
|
||||
bool obs_frontend_add_custom_qdock(const char *id, void *dock) override;
|
||||
|
||||
void obs_frontend_add_event_callback(obs_frontend_event_cb callback, void *private_data) override;
|
||||
|
||||
void obs_frontend_remove_event_callback(obs_frontend_event_cb callback, void *private_data) override;
|
||||
|
||||
obs_output_t *obs_frontend_get_streaming_output(void) override;
|
||||
|
||||
obs_output_t *obs_frontend_get_recording_output(void) override;
|
||||
|
||||
obs_output_t *obs_frontend_get_replay_buffer_output(void) override;
|
||||
|
||||
config_t *obs_frontend_get_profile_config(void) override;
|
||||
|
||||
config_t *obs_frontend_get_global_config(void) override;
|
||||
|
||||
config_t *obs_frontend_get_app_config(void) override;
|
||||
|
||||
config_t *obs_frontend_get_user_config(void) override;
|
||||
|
||||
void obs_frontend_open_projector(const char *type, int monitor, const char *geometry,
|
||||
const char *name) override;
|
||||
|
||||
void obs_frontend_save(void) override;
|
||||
|
||||
void obs_frontend_defer_save_begin(void) override;
|
||||
|
||||
void obs_frontend_defer_save_end(void) override;
|
||||
|
||||
void obs_frontend_add_save_callback(obs_frontend_save_cb callback, void *private_data) override;
|
||||
|
||||
void obs_frontend_remove_save_callback(obs_frontend_save_cb callback, void *private_data) override;
|
||||
|
||||
void obs_frontend_add_preload_callback(obs_frontend_save_cb callback, void *private_data) override;
|
||||
|
||||
void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback, void *private_data) override;
|
||||
|
||||
void obs_frontend_push_ui_translation(obs_frontend_translate_ui_cb translate) override;
|
||||
|
||||
void obs_frontend_pop_ui_translation(void) override;
|
||||
|
||||
void obs_frontend_set_streaming_service(obs_service_t *service) override;
|
||||
|
||||
obs_service_t *obs_frontend_get_streaming_service(void) override;
|
||||
|
||||
void obs_frontend_save_streaming_service(void) override;
|
||||
|
||||
bool obs_frontend_preview_program_mode_active(void) override;
|
||||
|
||||
void obs_frontend_set_preview_program_mode(bool enable) override;
|
||||
|
||||
void obs_frontend_preview_program_trigger_transition(void) override;
|
||||
|
||||
bool obs_frontend_preview_enabled(void) override;
|
||||
|
||||
void obs_frontend_set_preview_enabled(bool enable) override;
|
||||
|
||||
obs_source_t *obs_frontend_get_current_preview_scene(void) override;
|
||||
|
||||
void obs_frontend_set_current_preview_scene(obs_source_t *scene) override;
|
||||
|
||||
void obs_frontend_take_screenshot(void) override;
|
||||
|
||||
void obs_frontend_take_source_screenshot(obs_source_t *source) override;
|
||||
|
||||
obs_output_t *obs_frontend_get_virtualcam_output(void) override;
|
||||
|
||||
void obs_frontend_start_virtualcam(void) override;
|
||||
|
||||
void obs_frontend_stop_virtualcam(void) override;
|
||||
|
||||
bool obs_frontend_virtualcam_active(void) override;
|
||||
|
||||
void obs_frontend_reset_video(void) override;
|
||||
|
||||
void obs_frontend_open_source_properties(obs_source_t *source) override;
|
||||
|
||||
void obs_frontend_open_source_filters(obs_source_t *source) override;
|
||||
|
||||
void obs_frontend_open_source_interaction(obs_source_t *source) override;
|
||||
|
||||
void obs_frontend_open_sceneitem_edit_transform(obs_sceneitem_t *item) override;
|
||||
|
||||
char *obs_frontend_get_current_record_output_path(void) override;
|
||||
|
||||
const char *obs_frontend_get_locale_string(const char *string) override;
|
||||
|
||||
bool obs_frontend_is_theme_dark(void) override;
|
||||
|
||||
char *obs_frontend_get_last_recording(void) override;
|
||||
|
||||
char *obs_frontend_get_last_screenshot(void) override;
|
||||
|
||||
char *obs_frontend_get_last_replay(void) override;
|
||||
|
||||
void obs_frontend_add_undo_redo_action(const char *name, const undo_redo_cb undo, const undo_redo_cb redo,
|
||||
const char *undo_data, const char *redo_data, bool repeatable) override
|
||||
{
|
||||
main->undo_s.add_action(
|
||||
name, [undo](const std::string &data) { undo(data.c_str()); },
|
||||
[redo](const std::string &data) { redo(data.c_str()); }, undo_data, redo_data, repeatable);
|
||||
}
|
||||
const char *undo_data, const char *redo_data, bool repeatable) override;
|
||||
|
||||
void on_load(obs_data_t *settings) override
|
||||
{
|
||||
for (size_t i = saveCallbacks.size(); i > 0; i--) {
|
||||
auto cb = saveCallbacks[i - 1];
|
||||
cb.callback(settings, false, cb.private_data);
|
||||
}
|
||||
}
|
||||
void on_load(obs_data_t *settings) override;
|
||||
|
||||
void on_preload(obs_data_t *settings) override
|
||||
{
|
||||
for (size_t i = preloadCallbacks.size(); i > 0; i--) {
|
||||
auto cb = preloadCallbacks[i - 1];
|
||||
cb.callback(settings, false, cb.private_data);
|
||||
}
|
||||
}
|
||||
void on_preload(obs_data_t *settings) override;
|
||||
|
||||
void on_save(obs_data_t *settings) override
|
||||
{
|
||||
for (size_t i = saveCallbacks.size(); i > 0; i--) {
|
||||
auto cb = saveCallbacks[i - 1];
|
||||
cb.callback(settings, true, cb.private_data);
|
||||
}
|
||||
}
|
||||
void on_save(obs_data_t *settings) override;
|
||||
|
||||
void on_event(enum obs_frontend_event event) override
|
||||
{
|
||||
if (main->disableSaving && event != OBS_FRONTEND_EVENT_SCENE_COLLECTION_CLEANUP &&
|
||||
event != OBS_FRONTEND_EVENT_EXIT)
|
||||
return;
|
||||
|
||||
for (size_t i = callbacks.size(); i > 0; i--) {
|
||||
auto cb = callbacks[i - 1];
|
||||
cb.callback(event, cb.private_data);
|
||||
}
|
||||
}
|
||||
void on_event(enum obs_frontend_event event) override;
|
||||
};
|
||||
|
||||
obs_frontend_callbacks *InitializeAPIInterface(OBSBasic *main)
|
||||
{
|
||||
obs_frontend_callbacks *api = new OBSStudioAPI(main);
|
||||
obs_frontend_set_callbacks_internal(api);
|
||||
return api;
|
||||
}
|
||||
obs_frontend_callbacks *InitializeAPIInterface(OBSBasic *main);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,41 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTranslator>
|
||||
#include <QPointer>
|
||||
#include <QFileSystemWatcher>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <QSocketNotifier>
|
||||
#else
|
||||
#include <QSessionManager>
|
||||
#endif
|
||||
#include <obs.hpp>
|
||||
#include <util/lexer.h>
|
||||
#include <util/profiler.h>
|
||||
#include <util/util.hpp>
|
||||
#include <util/platform.h>
|
||||
#include <obs-frontend-api.h>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <filesystem>
|
||||
|
||||
#include "window-main.hpp"
|
||||
#include "obs-app-theming.hpp"
|
||||
|
||||
std::string CurrentTimeString();
|
||||
std::string CurrentDateTimeString();
|
||||
std::string GenerateTimeDateFilename(const char *extension, bool noSpace = false);
|
||||
std::string GenerateSpecifiedFilename(const char *extension, bool noSpace, const char *format);
|
||||
std::string GetFormatString(const char *format, const char *prefix, const char *suffix);
|
||||
std::string GetFormatExt(const char *container);
|
||||
std::string GetOutputFilename(const char *path, const char *container, bool noSpace, bool overwrite,
|
||||
const char *format);
|
||||
QObject *CreateShortcutFilter();
|
||||
|
||||
struct BaseLexer {
|
||||
lexer lex;
|
||||
@ -61,220 +27,3 @@ public:
|
||||
inline ~BaseLexer() { lexer_free(&lex); }
|
||||
operator lexer *() { return &lex; }
|
||||
};
|
||||
|
||||
class OBSTranslator : public QTranslator {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual bool isEmpty() const override { return false; }
|
||||
|
||||
virtual QString translate(const char *context, const char *sourceText, const char *disambiguation,
|
||||
int n) const override;
|
||||
};
|
||||
|
||||
typedef std::function<void()> VoidFunc;
|
||||
|
||||
struct UpdateBranch {
|
||||
QString name;
|
||||
QString display_name;
|
||||
QString description;
|
||||
bool is_enabled;
|
||||
bool is_visible;
|
||||
};
|
||||
|
||||
class OBSApp : public QApplication {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
std::string locale;
|
||||
|
||||
ConfigFile appConfig;
|
||||
ConfigFile userConfig;
|
||||
TextLookup textLookup;
|
||||
QPointer<OBSMainWindow> mainWindow;
|
||||
profiler_name_store_t *profilerNameStore = nullptr;
|
||||
std::vector<UpdateBranch> updateBranches;
|
||||
bool branches_loaded = false;
|
||||
|
||||
bool libobs_initialized = false;
|
||||
|
||||
os_inhibit_t *sleepInhibitor = nullptr;
|
||||
int sleepInhibitRefs = 0;
|
||||
|
||||
bool enableHotkeysInFocus = true;
|
||||
bool enableHotkeysOutOfFocus = true;
|
||||
|
||||
std::deque<obs_frontend_translate_ui_cb> translatorHooks;
|
||||
|
||||
bool UpdatePre22MultiviewLayout(const char *layout);
|
||||
|
||||
bool InitGlobalConfig();
|
||||
bool InitGlobalConfigDefaults();
|
||||
bool InitGlobalLocationDefaults();
|
||||
|
||||
bool MigrateGlobalSettings();
|
||||
void MigrateLegacySettings(uint32_t lastVersion);
|
||||
|
||||
bool InitUserConfig(std::filesystem::path &userConfigLocation, uint32_t lastVersion);
|
||||
void InitUserConfigDefaults();
|
||||
|
||||
bool InitLocale();
|
||||
bool InitTheme();
|
||||
|
||||
inline void ResetHotkeyState(bool inFocus);
|
||||
|
||||
QPalette defaultPalette;
|
||||
OBSTheme *currentTheme = nullptr;
|
||||
QHash<QString, OBSTheme> themes;
|
||||
QPointer<QFileSystemWatcher> themeWatcher;
|
||||
|
||||
void FindThemes();
|
||||
|
||||
bool notify(QObject *receiver, QEvent *e) override;
|
||||
|
||||
#ifndef _WIN32
|
||||
static int sigintFd[2];
|
||||
QSocketNotifier *snInt = nullptr;
|
||||
#else
|
||||
private slots:
|
||||
void commitData(QSessionManager &manager);
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
void themeFileChanged(const QString &);
|
||||
|
||||
public:
|
||||
OBSApp(int &argc, char **argv, profiler_name_store_t *store);
|
||||
~OBSApp();
|
||||
|
||||
void AppInit();
|
||||
bool OBSInit();
|
||||
|
||||
void UpdateHotkeyFocusSetting(bool reset = true);
|
||||
void DisableHotkeys();
|
||||
|
||||
inline bool HotkeysEnabledInFocus() const { return enableHotkeysInFocus; }
|
||||
|
||||
inline QMainWindow *GetMainWindow() const { return mainWindow.data(); }
|
||||
|
||||
inline config_t *GetAppConfig() const { return appConfig; }
|
||||
inline config_t *GetUserConfig() const { return userConfig; }
|
||||
std::filesystem::path userConfigLocation;
|
||||
std::filesystem::path userScenesLocation;
|
||||
std::filesystem::path userProfilesLocation;
|
||||
|
||||
inline const char *GetLocale() const { return locale.c_str(); }
|
||||
|
||||
OBSTheme *GetTheme() const { return currentTheme; }
|
||||
QList<OBSTheme> GetThemes() const { return themes.values(); }
|
||||
OBSTheme *GetTheme(const QString &name);
|
||||
bool SetTheme(const QString &name);
|
||||
bool IsThemeDark() const { return currentTheme ? currentTheme->isDark : false; }
|
||||
|
||||
void SetBranchData(const std::string &data);
|
||||
std::vector<UpdateBranch> GetBranches();
|
||||
|
||||
inline lookup_t *GetTextLookup() const { return textLookup; }
|
||||
|
||||
inline const char *GetString(const char *lookupVal) const { return textLookup.GetString(lookupVal); }
|
||||
|
||||
bool TranslateString(const char *lookupVal, const char **out) const;
|
||||
|
||||
profiler_name_store_t *GetProfilerNameStore() const { return profilerNameStore; }
|
||||
|
||||
const char *GetLastLog() const;
|
||||
const char *GetCurrentLog() const;
|
||||
|
||||
const char *GetLastCrashLog() const;
|
||||
|
||||
std::string GetVersionString(bool platform = true) const;
|
||||
bool IsPortableMode();
|
||||
bool IsUpdaterDisabled();
|
||||
bool IsMissingFilesCheckDisabled();
|
||||
|
||||
const char *InputAudioSource() const;
|
||||
const char *OutputAudioSource() const;
|
||||
|
||||
const char *GetRenderModule() const;
|
||||
|
||||
inline void IncrementSleepInhibition()
|
||||
{
|
||||
if (!sleepInhibitor)
|
||||
return;
|
||||
if (sleepInhibitRefs++ == 0)
|
||||
os_inhibit_sleep_set_active(sleepInhibitor, true);
|
||||
}
|
||||
|
||||
inline void DecrementSleepInhibition()
|
||||
{
|
||||
if (!sleepInhibitor)
|
||||
return;
|
||||
if (sleepInhibitRefs == 0)
|
||||
return;
|
||||
if (--sleepInhibitRefs == 0)
|
||||
os_inhibit_sleep_set_active(sleepInhibitor, false);
|
||||
}
|
||||
|
||||
inline void PushUITranslation(obs_frontend_translate_ui_cb cb) { translatorHooks.emplace_front(cb); }
|
||||
|
||||
inline void PopUITranslation() { translatorHooks.pop_front(); }
|
||||
#ifndef _WIN32
|
||||
static void SigIntSignalHandler(int);
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
void Exec(VoidFunc func);
|
||||
void ProcessSigInt();
|
||||
|
||||
signals:
|
||||
void StyleChanged();
|
||||
};
|
||||
|
||||
int GetAppConfigPath(char *path, size_t size, const char *name);
|
||||
char *GetAppConfigPathPtr(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);
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> GetLocaleNames();
|
||||
inline const char *Str(const char *lookup)
|
||||
{
|
||||
return App()->GetString(lookup);
|
||||
}
|
||||
inline QString QTStr(const char *lookupVal)
|
||||
{
|
||||
return QString::fromUtf8(Str(lookupVal));
|
||||
}
|
||||
|
||||
bool GetFileSafeName(const char *name, std::string &file);
|
||||
bool GetClosestUnusedFileName(std::string &path, const char *extension);
|
||||
bool GetUnusedSceneCollectionFile(std::string &name, std::string &file);
|
||||
|
||||
bool WindowPositionValid(QRect rect);
|
||||
|
||||
extern bool portable_mode;
|
||||
extern bool steam;
|
||||
extern bool safe_mode;
|
||||
extern bool disable_3p_plugins;
|
||||
|
||||
extern bool opt_start_streaming;
|
||||
extern bool opt_start_recording;
|
||||
extern bool opt_start_replaybuffer;
|
||||
extern bool opt_start_virtualcam;
|
||||
extern bool opt_minimize_tray;
|
||||
extern bool opt_studio_mode;
|
||||
extern bool opt_allow_opengl;
|
||||
extern bool opt_always_on_top;
|
||||
extern std::string opt_starting_scene;
|
||||
extern bool restart;
|
||||
extern bool restart_safe;
|
||||
|
||||
#ifdef _WIN32
|
||||
extern "C" void install_dll_blocklist_hook(void);
|
||||
extern "C" void log_blocked_dlls(void);
|
||||
#endif
|
||||
|
@ -17,12 +17,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
struct OBSThemeVariable;
|
||||
|
||||
struct OBSTheme {
|
||||
/* internal name, must be unique */
|
||||
QString id;
|
||||
@ -43,24 +42,3 @@ struct OBSTheme {
|
||||
bool isBaseTheme; /* Whether it is a "style" or variant */
|
||||
bool isHighContrast; /* Whether it is a high-contrast adjustment layer */
|
||||
};
|
||||
|
||||
struct OBSThemeVariable {
|
||||
enum VariableType {
|
||||
Color, /* RGB color value*/
|
||||
Size, /* Number with suffix denoting size (e.g. px, pt, em) */
|
||||
Number, /* Number without suffix */
|
||||
String, /* Raw string (e.g. color name, border style, etc.) */
|
||||
Alias, /* Points at another variable, value will be the key */
|
||||
Calc, /* Simple calculation with two operands */
|
||||
};
|
||||
|
||||
/* Whether the variable should be editable in the UI */
|
||||
bool editable = false;
|
||||
/* Used for VariableType::Size only */
|
||||
QString suffix;
|
||||
|
||||
VariableType type;
|
||||
QString name;
|
||||
QVariant value;
|
||||
QVariant userValue; /* If overwritten by user, use this value instead */
|
||||
};
|
||||
|
@ -17,33 +17,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
struct OBSThemeVariable;
|
||||
|
||||
struct OBSTheme {
|
||||
/* internal name, must be unique */
|
||||
QString id;
|
||||
QString name;
|
||||
QString author;
|
||||
QString extends;
|
||||
|
||||
/* First ancestor base theme */
|
||||
QString parent;
|
||||
/* Dependencies from root to direct ancestor */
|
||||
QStringList dependencies;
|
||||
/* File path */
|
||||
std::filesystem::path location;
|
||||
std::filesystem::path filename; /* Filename without extension */
|
||||
|
||||
bool isDark;
|
||||
bool isVisible; /* Whether it should be shown to the user */
|
||||
bool isBaseTheme; /* Whether it is a "style" or variant */
|
||||
bool isHighContrast; /* Whether it is a high-contrast adjustment layer */
|
||||
};
|
||||
|
||||
struct OBSThemeVariable {
|
||||
enum VariableType {
|
||||
Color, /* RGB color value*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,50 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QApplication>
|
||||
#include <QString>
|
||||
#include <QTranslator>
|
||||
#include <QPointer>
|
||||
#include <QFileSystemWatcher>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <QSocketNotifier>
|
||||
#else
|
||||
#include <QSessionManager>
|
||||
#endif
|
||||
#include <obs.hpp>
|
||||
#include <util/lexer.h>
|
||||
#include <util/profiler.h>
|
||||
#include <util/util.hpp>
|
||||
#include <util/platform.h>
|
||||
#include <obs-frontend-api.h>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <filesystem>
|
||||
|
||||
#include "window-main.hpp"
|
||||
#include "obs-app-theming.hpp"
|
||||
|
||||
std::string CurrentTimeString();
|
||||
std::string CurrentDateTimeString();
|
||||
std::string GenerateTimeDateFilename(const char *extension, bool noSpace = false);
|
||||
std::string GenerateSpecifiedFilename(const char *extension, bool noSpace, const char *format);
|
||||
std::string GetFormatString(const char *format, const char *prefix, const char *suffix);
|
||||
std::string GetFormatExt(const char *container);
|
||||
std::string GetOutputFilename(const char *path, const char *container, bool noSpace, bool overwrite,
|
||||
const char *format);
|
||||
QObject *CreateShortcutFilter();
|
||||
|
||||
struct BaseLexer {
|
||||
lexer lex;
|
||||
|
||||
public:
|
||||
inline BaseLexer() { lexer_init(&lex); }
|
||||
inline ~BaseLexer() { lexer_free(&lex); }
|
||||
operator lexer *() { return &lex; }
|
||||
};
|
||||
|
||||
class OBSTranslator : public QTranslator {
|
||||
Q_OBJECT
|
||||
@ -71,210 +29,3 @@ public:
|
||||
virtual QString translate(const char *context, const char *sourceText, const char *disambiguation,
|
||||
int n) const override;
|
||||
};
|
||||
|
||||
typedef std::function<void()> VoidFunc;
|
||||
|
||||
struct UpdateBranch {
|
||||
QString name;
|
||||
QString display_name;
|
||||
QString description;
|
||||
bool is_enabled;
|
||||
bool is_visible;
|
||||
};
|
||||
|
||||
class OBSApp : public QApplication {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
std::string locale;
|
||||
|
||||
ConfigFile appConfig;
|
||||
ConfigFile userConfig;
|
||||
TextLookup textLookup;
|
||||
QPointer<OBSMainWindow> mainWindow;
|
||||
profiler_name_store_t *profilerNameStore = nullptr;
|
||||
std::vector<UpdateBranch> updateBranches;
|
||||
bool branches_loaded = false;
|
||||
|
||||
bool libobs_initialized = false;
|
||||
|
||||
os_inhibit_t *sleepInhibitor = nullptr;
|
||||
int sleepInhibitRefs = 0;
|
||||
|
||||
bool enableHotkeysInFocus = true;
|
||||
bool enableHotkeysOutOfFocus = true;
|
||||
|
||||
std::deque<obs_frontend_translate_ui_cb> translatorHooks;
|
||||
|
||||
bool UpdatePre22MultiviewLayout(const char *layout);
|
||||
|
||||
bool InitGlobalConfig();
|
||||
bool InitGlobalConfigDefaults();
|
||||
bool InitGlobalLocationDefaults();
|
||||
|
||||
bool MigrateGlobalSettings();
|
||||
void MigrateLegacySettings(uint32_t lastVersion);
|
||||
|
||||
bool InitUserConfig(std::filesystem::path &userConfigLocation, uint32_t lastVersion);
|
||||
void InitUserConfigDefaults();
|
||||
|
||||
bool InitLocale();
|
||||
bool InitTheme();
|
||||
|
||||
inline void ResetHotkeyState(bool inFocus);
|
||||
|
||||
QPalette defaultPalette;
|
||||
OBSTheme *currentTheme = nullptr;
|
||||
QHash<QString, OBSTheme> themes;
|
||||
QPointer<QFileSystemWatcher> themeWatcher;
|
||||
|
||||
void FindThemes();
|
||||
|
||||
bool notify(QObject *receiver, QEvent *e) override;
|
||||
|
||||
#ifndef _WIN32
|
||||
static int sigintFd[2];
|
||||
QSocketNotifier *snInt = nullptr;
|
||||
#else
|
||||
private slots:
|
||||
void commitData(QSessionManager &manager);
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
void themeFileChanged(const QString &);
|
||||
|
||||
public:
|
||||
OBSApp(int &argc, char **argv, profiler_name_store_t *store);
|
||||
~OBSApp();
|
||||
|
||||
void AppInit();
|
||||
bool OBSInit();
|
||||
|
||||
void UpdateHotkeyFocusSetting(bool reset = true);
|
||||
void DisableHotkeys();
|
||||
|
||||
inline bool HotkeysEnabledInFocus() const { return enableHotkeysInFocus; }
|
||||
|
||||
inline QMainWindow *GetMainWindow() const { return mainWindow.data(); }
|
||||
|
||||
inline config_t *GetAppConfig() const { return appConfig; }
|
||||
inline config_t *GetUserConfig() const { return userConfig; }
|
||||
std::filesystem::path userConfigLocation;
|
||||
std::filesystem::path userScenesLocation;
|
||||
std::filesystem::path userProfilesLocation;
|
||||
|
||||
inline const char *GetLocale() const { return locale.c_str(); }
|
||||
|
||||
OBSTheme *GetTheme() const { return currentTheme; }
|
||||
QList<OBSTheme> GetThemes() const { return themes.values(); }
|
||||
OBSTheme *GetTheme(const QString &name);
|
||||
bool SetTheme(const QString &name);
|
||||
bool IsThemeDark() const { return currentTheme ? currentTheme->isDark : false; }
|
||||
|
||||
void SetBranchData(const std::string &data);
|
||||
std::vector<UpdateBranch> GetBranches();
|
||||
|
||||
inline lookup_t *GetTextLookup() const { return textLookup; }
|
||||
|
||||
inline const char *GetString(const char *lookupVal) const { return textLookup.GetString(lookupVal); }
|
||||
|
||||
bool TranslateString(const char *lookupVal, const char **out) const;
|
||||
|
||||
profiler_name_store_t *GetProfilerNameStore() const { return profilerNameStore; }
|
||||
|
||||
const char *GetLastLog() const;
|
||||
const char *GetCurrentLog() const;
|
||||
|
||||
const char *GetLastCrashLog() const;
|
||||
|
||||
std::string GetVersionString(bool platform = true) const;
|
||||
bool IsPortableMode();
|
||||
bool IsUpdaterDisabled();
|
||||
bool IsMissingFilesCheckDisabled();
|
||||
|
||||
const char *InputAudioSource() const;
|
||||
const char *OutputAudioSource() const;
|
||||
|
||||
const char *GetRenderModule() const;
|
||||
|
||||
inline void IncrementSleepInhibition()
|
||||
{
|
||||
if (!sleepInhibitor)
|
||||
return;
|
||||
if (sleepInhibitRefs++ == 0)
|
||||
os_inhibit_sleep_set_active(sleepInhibitor, true);
|
||||
}
|
||||
|
||||
inline void DecrementSleepInhibition()
|
||||
{
|
||||
if (!sleepInhibitor)
|
||||
return;
|
||||
if (sleepInhibitRefs == 0)
|
||||
return;
|
||||
if (--sleepInhibitRefs == 0)
|
||||
os_inhibit_sleep_set_active(sleepInhibitor, false);
|
||||
}
|
||||
|
||||
inline void PushUITranslation(obs_frontend_translate_ui_cb cb) { translatorHooks.emplace_front(cb); }
|
||||
|
||||
inline void PopUITranslation() { translatorHooks.pop_front(); }
|
||||
#ifndef _WIN32
|
||||
static void SigIntSignalHandler(int);
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
void Exec(VoidFunc func);
|
||||
void ProcessSigInt();
|
||||
|
||||
signals:
|
||||
void StyleChanged();
|
||||
};
|
||||
|
||||
int GetAppConfigPath(char *path, size_t size, const char *name);
|
||||
char *GetAppConfigPathPtr(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);
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> GetLocaleNames();
|
||||
inline const char *Str(const char *lookup)
|
||||
{
|
||||
return App()->GetString(lookup);
|
||||
}
|
||||
inline QString QTStr(const char *lookupVal)
|
||||
{
|
||||
return QString::fromUtf8(Str(lookupVal));
|
||||
}
|
||||
|
||||
bool GetFileSafeName(const char *name, std::string &file);
|
||||
bool GetClosestUnusedFileName(std::string &path, const char *extension);
|
||||
bool GetUnusedSceneCollectionFile(std::string &name, std::string &file);
|
||||
|
||||
bool WindowPositionValid(QRect rect);
|
||||
|
||||
extern bool portable_mode;
|
||||
extern bool steam;
|
||||
extern bool safe_mode;
|
||||
extern bool disable_3p_plugins;
|
||||
|
||||
extern bool opt_start_streaming;
|
||||
extern bool opt_start_recording;
|
||||
extern bool opt_start_replaybuffer;
|
||||
extern bool opt_start_virtualcam;
|
||||
extern bool opt_minimize_tray;
|
||||
extern bool opt_studio_mode;
|
||||
extern bool opt_allow_opengl;
|
||||
extern bool opt_always_on_top;
|
||||
extern std::string opt_starting_scene;
|
||||
extern bool restart;
|
||||
extern bool restart_safe;
|
||||
|
||||
#ifdef _WIN32
|
||||
extern "C" void install_dll_blocklist_hook(void);
|
||||
extern "C" void log_blocked_dlls(void);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user