obs-studio/UI/obs-app.hpp

257 lines
6.7 KiB
C++
Raw Permalink Normal View History

/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
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
Change the UI to Qt (work in progress) -------------------------------------------------- Notes and details -------------------------------------------------- Why was this done? Because wxWidgets was just lacking in many areas. I know wxWidgets is designed to be used with native controls, and that's great, but wxWidgets just is not a feature-complete toolkit for multiplatform applications. It lacks in dialog editors, its code is archaic and outdated, and I just feel frustrated every time I try to do things with it. Qt on the other hand.. I had to actually try Qt to realize how much better it was as a toolkit. They've got everything from dialog editors, to an IDE, a debugger, build tools, just everything, and it's all top-notch and highly maintained. The focus of the toolkit is application development, and they spend their time trying to help people do exactly that: make programs. Great support, great tools, and because of that, great toolkit. I just didn't want to alienate any developers by being stubborn about native widgets. There *are* some things that are rather lackluster about it and design choices I disagree with though. For example, I realize that to have an easy to use toolkit you have to have some level of code generation. However, in my personal and humble opinion, moc just feels like a terrible way to approach the problem. Even now I feel like there are a variety of ways you could handle code generation and automatic management of things like that. I don't like the idea of circumventing the language itself like that. It feels like one giant massive hack. -------------------------------------------------- Things that aren't working properly: -------------------------------------------------- - Settings dialog is not implemented. The dialog is complete but the code to handle the dialog hasn't been constructed yet. - There is a problem with using Qt widgets as a device target on windows, with at least OpenGL: if I have the preview widget automatically resize itself, it seems to cause some sort of video card failure that I don't understand. - Because of the above, resizing the preview widget has been disabled until I can figure out what's going on, so it's currently only a 32x32 area. - Direct3D doesn't seem to render correctly either, seems that the viewport is messed up or something. I'm sort of confused about what's going on with it. - The new main window seems to be triggering more race conditions than the wxWidgets main window dialog did. I'm not entirely sure what's going on here, but this may just be existing race conditions within libobs itself that I just never spotted before (even though I tend to be very thorough with race conditions any time I use variables cross-thread)
2014-01-23 10:53:55 -08:00
#include <QApplication>
#include <QTranslator>
#include <QPointer>
#include <obs.hpp>
#include <util/lexer.h>
2015-07-10 23:03:31 -07:00
#include <util/profiler.h>
2013-12-22 16:42:02 -08:00
#include <util/util.hpp>
#include <util/platform.h>
#include <obs-frontend-api.h>
#include <functional>
#include <string>
Change the UI to Qt (work in progress) -------------------------------------------------- Notes and details -------------------------------------------------- Why was this done? Because wxWidgets was just lacking in many areas. I know wxWidgets is designed to be used with native controls, and that's great, but wxWidgets just is not a feature-complete toolkit for multiplatform applications. It lacks in dialog editors, its code is archaic and outdated, and I just feel frustrated every time I try to do things with it. Qt on the other hand.. I had to actually try Qt to realize how much better it was as a toolkit. They've got everything from dialog editors, to an IDE, a debugger, build tools, just everything, and it's all top-notch and highly maintained. The focus of the toolkit is application development, and they spend their time trying to help people do exactly that: make programs. Great support, great tools, and because of that, great toolkit. I just didn't want to alienate any developers by being stubborn about native widgets. There *are* some things that are rather lackluster about it and design choices I disagree with though. For example, I realize that to have an easy to use toolkit you have to have some level of code generation. However, in my personal and humble opinion, moc just feels like a terrible way to approach the problem. Even now I feel like there are a variety of ways you could handle code generation and automatic management of things like that. I don't like the idea of circumventing the language itself like that. It feels like one giant massive hack. -------------------------------------------------- Things that aren't working properly: -------------------------------------------------- - Settings dialog is not implemented. The dialog is complete but the code to handle the dialog hasn't been constructed yet. - There is a problem with using Qt widgets as a device target on windows, with at least OpenGL: if I have the preview widget automatically resize itself, it seems to cause some sort of video card failure that I don't understand. - Because of the above, resizing the preview widget has been disabled until I can figure out what's going on, so it's currently only a 32x32 area. - Direct3D doesn't seem to render correctly either, seems that the viewport is messed up or something. I'm sort of confused about what's going on with it. - The new main window seems to be triggering more race conditions than the wxWidgets main window dialog did. I'm not entirely sure what's going on here, but this may just be existing race conditions within libobs itself that I just never spotted before (even though I tend to be very thorough with race conditions any time I use variables cross-thread)
2014-01-23 10:53:55 -08:00
#include <memory>
#include <vector>
#include <deque>
#include "window-main.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);
2020-07-23 06:45:03 -07:00
std::string GetFormatString(const char *format, const char *prefix,
const char *suffix);
std::string GetOutputFilename(const char *path, const char *ext, bool noSpace,
bool overwrite, const char *format);
2014-11-01 13:48:58 -07:00
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;
struct OBSThemeMeta {
bool dark;
std::string parent;
std::string author;
};
Change the UI to Qt (work in progress) -------------------------------------------------- Notes and details -------------------------------------------------- Why was this done? Because wxWidgets was just lacking in many areas. I know wxWidgets is designed to be used with native controls, and that's great, but wxWidgets just is not a feature-complete toolkit for multiplatform applications. It lacks in dialog editors, its code is archaic and outdated, and I just feel frustrated every time I try to do things with it. Qt on the other hand.. I had to actually try Qt to realize how much better it was as a toolkit. They've got everything from dialog editors, to an IDE, a debugger, build tools, just everything, and it's all top-notch and highly maintained. The focus of the toolkit is application development, and they spend their time trying to help people do exactly that: make programs. Great support, great tools, and because of that, great toolkit. I just didn't want to alienate any developers by being stubborn about native widgets. There *are* some things that are rather lackluster about it and design choices I disagree with though. For example, I realize that to have an easy to use toolkit you have to have some level of code generation. However, in my personal and humble opinion, moc just feels like a terrible way to approach the problem. Even now I feel like there are a variety of ways you could handle code generation and automatic management of things like that. I don't like the idea of circumventing the language itself like that. It feels like one giant massive hack. -------------------------------------------------- Things that aren't working properly: -------------------------------------------------- - Settings dialog is not implemented. The dialog is complete but the code to handle the dialog hasn't been constructed yet. - There is a problem with using Qt widgets as a device target on windows, with at least OpenGL: if I have the preview widget automatically resize itself, it seems to cause some sort of video card failure that I don't understand. - Because of the above, resizing the preview widget has been disabled until I can figure out what's going on, so it's currently only a 32x32 area. - Direct3D doesn't seem to render correctly either, seems that the viewport is messed up or something. I'm sort of confused about what's going on with it. - The new main window seems to be triggering more race conditions than the wxWidgets main window dialog did. I'm not entirely sure what's going on here, but this may just be existing race conditions within libobs itself that I just never spotted before (even though I tend to be very thorough with race conditions any time I use variables cross-thread)
2014-01-23 10:53:55 -08:00
class OBSApp : public QApplication {
Q_OBJECT
Change the UI to Qt (work in progress) -------------------------------------------------- Notes and details -------------------------------------------------- Why was this done? Because wxWidgets was just lacking in many areas. I know wxWidgets is designed to be used with native controls, and that's great, but wxWidgets just is not a feature-complete toolkit for multiplatform applications. It lacks in dialog editors, its code is archaic and outdated, and I just feel frustrated every time I try to do things with it. Qt on the other hand.. I had to actually try Qt to realize how much better it was as a toolkit. They've got everything from dialog editors, to an IDE, a debugger, build tools, just everything, and it's all top-notch and highly maintained. The focus of the toolkit is application development, and they spend their time trying to help people do exactly that: make programs. Great support, great tools, and because of that, great toolkit. I just didn't want to alienate any developers by being stubborn about native widgets. There *are* some things that are rather lackluster about it and design choices I disagree with though. For example, I realize that to have an easy to use toolkit you have to have some level of code generation. However, in my personal and humble opinion, moc just feels like a terrible way to approach the problem. Even now I feel like there are a variety of ways you could handle code generation and automatic management of things like that. I don't like the idea of circumventing the language itself like that. It feels like one giant massive hack. -------------------------------------------------- Things that aren't working properly: -------------------------------------------------- - Settings dialog is not implemented. The dialog is complete but the code to handle the dialog hasn't been constructed yet. - There is a problem with using Qt widgets as a device target on windows, with at least OpenGL: if I have the preview widget automatically resize itself, it seems to cause some sort of video card failure that I don't understand. - Because of the above, resizing the preview widget has been disabled until I can figure out what's going on, so it's currently only a 32x32 area. - Direct3D doesn't seem to render correctly either, seems that the viewport is messed up or something. I'm sort of confused about what's going on with it. - The new main window seems to be triggering more race conditions than the wxWidgets main window dialog did. I'm not entirely sure what's going on here, but this may just be existing race conditions within libobs itself that I just never spotted before (even though I tend to be very thorough with race conditions any time I use variables cross-thread)
2014-01-23 10:53:55 -08:00
private:
std::string locale;
std::string theme;
bool themeDarkMode = true;
ConfigFile globalConfig;
TextLookup textLookup;
QPointer<OBSMainWindow> mainWindow;
profiler_name_store_t *profilerNameStore = nullptr;
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 InitLocale();
bool InitTheme();
inline void ResetHotkeyState(bool inFocus);
QPalette defaultPalette;
void ParseExtraThemeData(const char *path);
static OBSThemeMeta *ParseThemeMeta(const char *path);
void AddExtraThemeColor(QPalette &pal, int group, const char *name,
uint32_t color);
bool notify(QObject *receiver, QEvent *e) override;
public:
2015-07-10 23:03:31 -07:00
OBSApp(int &argc, char **argv, profiler_name_store_t *store);
~OBSApp();
void AppInit();
2014-07-13 11:36:47 -07:00
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 *GlobalConfig() const { return globalConfig; }
inline const char *GetLocale() const { return locale.c_str(); }
inline const char *GetTheme() const { return theme.c_str(); }
std::string GetTheme(std::string name, std::string path);
std::string SetParentTheme(std::string name);
bool SetTheme(std::string name, std::string path = "");
inline bool IsThemeDark() const { return themeDarkMode; };
inline lookup_t *GetTextLookup() const { return textLookup; }
inline const char *GetString(const char *lookupVal) const
{
return textLookup.GetString(lookupVal);
2015-07-10 23:03:31 -07:00
}
bool TranslateString(const char *lookupVal, const char **out) const;
2015-07-10 23:03:31 -07:00
profiler_name_store_t *GetProfilerNameStore() const
{
return profilerNameStore;
}
const char *GetLastLog() const;
const char *GetCurrentLog() const;
const char *GetLastCrashLog() const;
std::string GetVersionString() 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(); }
public slots:
void Exec(VoidFunc func);
signals:
void StyleChanged();
};
int GetConfigPath(char *path, size_t size, const char *name);
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 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);
}
Change the UI to Qt (work in progress) -------------------------------------------------- Notes and details -------------------------------------------------- Why was this done? Because wxWidgets was just lacking in many areas. I know wxWidgets is designed to be used with native controls, and that's great, but wxWidgets just is not a feature-complete toolkit for multiplatform applications. It lacks in dialog editors, its code is archaic and outdated, and I just feel frustrated every time I try to do things with it. Qt on the other hand.. I had to actually try Qt to realize how much better it was as a toolkit. They've got everything from dialog editors, to an IDE, a debugger, build tools, just everything, and it's all top-notch and highly maintained. The focus of the toolkit is application development, and they spend their time trying to help people do exactly that: make programs. Great support, great tools, and because of that, great toolkit. I just didn't want to alienate any developers by being stubborn about native widgets. There *are* some things that are rather lackluster about it and design choices I disagree with though. For example, I realize that to have an easy to use toolkit you have to have some level of code generation. However, in my personal and humble opinion, moc just feels like a terrible way to approach the problem. Even now I feel like there are a variety of ways you could handle code generation and automatic management of things like that. I don't like the idea of circumventing the language itself like that. It feels like one giant massive hack. -------------------------------------------------- Things that aren't working properly: -------------------------------------------------- - Settings dialog is not implemented. The dialog is complete but the code to handle the dialog hasn't been constructed yet. - There is a problem with using Qt widgets as a device target on windows, with at least OpenGL: if I have the preview widget automatically resize itself, it seems to cause some sort of video card failure that I don't understand. - Because of the above, resizing the preview widget has been disabled until I can figure out what's going on, so it's currently only a 32x32 area. - Direct3D doesn't seem to render correctly either, seems that the viewport is messed up or something. I'm sort of confused about what's going on with it. - The new main window seems to be triggering more race conditions than the wxWidgets main window dialog did. I'm not entirely sure what's going on here, but this may just be existing race conditions within libobs itself that I just never spotted before (even though I tend to be very thorough with race conditions any time I use variables cross-thread)
2014-01-23 10:53:55 -08:00
#define QTStr(lookupVal) 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);
static inline int GetProfilePath(char *path, size_t size, const char *file)
{
OBSMainWindow *window =
reinterpret_cast<OBSMainWindow *>(App()->GetMainWindow());
return window->GetProfilePath(path, size, file);
}
extern bool portable_mode;
2017-05-08 04:53:35 -07:00
extern bool opt_start_streaming;
extern bool opt_start_recording;
2017-01-11 11:19:17 -08:00
extern bool opt_start_replaybuffer;
extern bool opt_start_virtualcam;
2017-01-11 11:19:17 -08:00
extern bool opt_minimize_tray;
extern bool opt_studio_mode;
extern bool opt_allow_opengl;
extern bool opt_always_on_top;
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
extern bool opt_disable_high_dpi_scaling;
#endif
extern std::string opt_starting_scene;
extern bool restart;