UI: Add support for theme meta, parent theme palette
Theme Meta allows individual themes to provide additional information to OBS. The primarily goal is for a theme to define a "parent", allowing to extend existing themes with additional attributes.master
parent
bf65c5b041
commit
cb8bc3413a
|
@ -1,3 +1,8 @@
|
||||||
|
OBSThemeMeta {
|
||||||
|
dark: 'true';
|
||||||
|
author: 'Warchamp7';
|
||||||
|
}
|
||||||
|
|
||||||
/* OBSTheme, main QApplication palette and QML values */
|
/* OBSTheme, main QApplication palette and QML values */
|
||||||
OBSTheme {
|
OBSTheme {
|
||||||
window: rgb(24,24,25);
|
window: rgb(24,24,25);
|
||||||
|
|
|
@ -28,6 +28,10 @@
|
||||||
/* rgb(11,10,11); /* veryVeryDark */
|
/* rgb(11,10,11); /* veryVeryDark */
|
||||||
/* rgb(42,130,218); /* blue */
|
/* rgb(42,130,218); /* blue */
|
||||||
|
|
||||||
|
OBSThemeMeta {
|
||||||
|
dark: 'true';
|
||||||
|
author: 'Warchamp7';
|
||||||
|
}
|
||||||
|
|
||||||
/* Custom theme information. This will set the application's QPalette, as
|
/* Custom theme information. This will set the application's QPalette, as
|
||||||
* well as pass to QML via the OBSTheme object.
|
* well as pass to QML via the OBSTheme object.
|
||||||
|
|
|
@ -44,6 +44,11 @@
|
||||||
/* ---- Main Theme ---- */
|
/* ---- Main Theme ---- */
|
||||||
/************************/
|
/************************/
|
||||||
|
|
||||||
|
OBSThemeMeta {
|
||||||
|
dark: 'true';
|
||||||
|
author: 'Fenrir';
|
||||||
|
}
|
||||||
|
|
||||||
OBSTheme {
|
OBSTheme {
|
||||||
window: rgb(49, 54, 59); /* Blue-gray */
|
window: rgb(49, 54, 59); /* Blue-gray */
|
||||||
windowText: rgb(239, 240, 241); /* White */
|
windowText: rgb(239, 240, 241); /* White */
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
/* Dark Theme is a good place to start if you need */
|
/* Dark Theme is a good place to start if you need */
|
||||||
/* a template. */
|
/* a template. */
|
||||||
|
|
||||||
|
OBSThemeMeta {
|
||||||
|
dark: 'false';
|
||||||
|
}
|
||||||
|
|
||||||
/* We need to set back the icons, or the preview wont stick. */
|
/* We need to set back the icons, or the preview wont stick. */
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,11 @@
|
||||||
|
|
||||||
/* Colors */
|
/* Colors */
|
||||||
|
|
||||||
|
OBSThemeMeta {
|
||||||
|
dark: 'true';
|
||||||
|
author: 'Warchamp7';
|
||||||
|
}
|
||||||
|
|
||||||
/* Custom theme information. This will set the application's QPalette, as
|
/* Custom theme information. This will set the application's QPalette, as
|
||||||
* well as pass to QML via the OBSTheme object.
|
* well as pass to QML via the OBSTheme object.
|
||||||
* Can also use OBSTheme::disabled, OBSTheme::active, and OBSTheme::inactive.
|
* Can also use OBSTheme::disabled, OBSTheme::active, and OBSTheme::inactive.
|
||||||
|
|
111
UI/obs-app.cpp
111
UI/obs-app.cpp
|
@ -1095,10 +1095,72 @@ void OBSApp::ParseExtraThemeData(const char *path)
|
||||||
setPalette(pal);
|
setPalette(pal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OBSApp::SetTheme(std::string name, std::string path)
|
OBSThemeMeta *OBSApp::ParseThemeMeta(const char *path)
|
||||||
{
|
{
|
||||||
theme = name;
|
BPtr<char> data = os_quick_read_utf8_file(path);
|
||||||
|
CFParser cfp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!cf_parser_parse(cfp, data, path))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (cf_token_is(cfp, "OBSThemeMeta") ||
|
||||||
|
cf_go_to_token(cfp, "OBSThemeMeta", nullptr)) {
|
||||||
|
OBSThemeMeta *meta = new OBSThemeMeta();
|
||||||
|
if (!cf_next_token(cfp))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (!cf_token_is(cfp, "{"))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (!cf_next_token(cfp))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
ret = cf_token_is_type(cfp, CFTOKEN_NAME, "name",
|
||||||
|
nullptr);
|
||||||
|
if (ret != PARSE_SUCCESS)
|
||||||
|
break;
|
||||||
|
|
||||||
|
DStr name;
|
||||||
|
dstr_copy_strref(name, &cfp->cur_token->str);
|
||||||
|
|
||||||
|
ret = cf_next_token_should_be(cfp, ":", ";", nullptr);
|
||||||
|
if (ret != PARSE_SUCCESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!cf_next_token(cfp))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
ret = cf_token_is_type(cfp, CFTOKEN_STRING, "value",
|
||||||
|
";");
|
||||||
|
|
||||||
|
if (ret != PARSE_SUCCESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char *str;
|
||||||
|
str = cf_literal_to_str(cfp->cur_token->str.array,
|
||||||
|
cfp->cur_token->str.len);
|
||||||
|
|
||||||
|
if (strcmp(name->array, "dark") == 0 && str) {
|
||||||
|
meta->dark = strcmp(str, "true") == 0;
|
||||||
|
} else if (strcmp(name->array, "parent") == 0 && str) {
|
||||||
|
meta->parent = std::string(str);
|
||||||
|
} else if (strcmp(name->array, "author") == 0 && str) {
|
||||||
|
meta->author = std::string(str);
|
||||||
|
}
|
||||||
|
bfree(str);
|
||||||
|
|
||||||
|
if (!cf_go_to_token(cfp, ";", nullptr))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string OBSApp::GetTheme(std::string name, std::string path)
|
||||||
|
{
|
||||||
/* Check user dir first, then preinstalled themes. */
|
/* Check user dir first, then preinstalled themes. */
|
||||||
if (path == "") {
|
if (path == "") {
|
||||||
char userDir[512];
|
char userDir[512];
|
||||||
|
@ -1110,18 +1172,59 @@ bool OBSApp::SetTheme(std::string name, std::string path)
|
||||||
path = string(userDir);
|
path = string(userDir);
|
||||||
} else if (!GetDataFilePath(name.c_str(), path)) {
|
} else if (!GetDataFilePath(name.c_str(), path)) {
|
||||||
OBSErrorBox(NULL, "Failed to find %s.", name.c_str());
|
OBSErrorBox(NULL, "Failed to find %s.", name.c_str());
|
||||||
return false;
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string OBSApp::SetParentTheme(std::string name)
|
||||||
|
{
|
||||||
|
string path = GetTheme(name.c_str(), "");
|
||||||
|
if (path.empty())
|
||||||
|
return path;
|
||||||
|
|
||||||
setStyleSheet(defaultStyleSheet);
|
setStyleSheet(defaultStyleSheet);
|
||||||
QString mpath = QString("file:///") + path.c_str();
|
|
||||||
setPalette(defaultPalette);
|
setPalette(defaultPalette);
|
||||||
|
|
||||||
|
QString mpath = QString("file:///") + path.c_str();
|
||||||
|
ParseExtraThemeData(path.c_str());
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OBSApp::SetTheme(std::string name, std::string path)
|
||||||
|
{
|
||||||
|
theme = name;
|
||||||
|
|
||||||
|
path = GetTheme(name, path);
|
||||||
|
if (path.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
themeMeta = ParseThemeMeta(path.c_str());
|
||||||
|
string parentPath;
|
||||||
|
|
||||||
|
if (themeMeta && !themeMeta->parent.empty()) {
|
||||||
|
parentPath = SetParentTheme(themeMeta->parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
string lpath = path;
|
||||||
|
if (parentPath.empty()) {
|
||||||
|
setStyleSheet(defaultStyleSheet);
|
||||||
|
setPalette(defaultPalette);
|
||||||
|
} else {
|
||||||
|
lpath = parentPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString mpath = QString("file:///") + lpath.c_str();
|
||||||
ParseExtraThemeData(path.c_str());
|
ParseExtraThemeData(path.c_str());
|
||||||
setStyle(new OBSIgnoreWheelProxyStyle);
|
setStyle(new OBSIgnoreWheelProxyStyle);
|
||||||
setStyleSheet(mpath);
|
setStyleSheet(mpath);
|
||||||
|
if (themeMeta) {
|
||||||
|
themeDarkMode = themeMeta->dark;
|
||||||
|
} else {
|
||||||
QColor color = palette().text().color();
|
QColor color = palette().text().color();
|
||||||
themeDarkMode = !(color.redF() < 0.5);
|
themeDarkMode = !(color.redF() < 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
emit StyleChanged();
|
emit StyleChanged();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -68,6 +68,12 @@ public:
|
||||||
|
|
||||||
typedef std::function<void()> VoidFunc;
|
typedef std::function<void()> VoidFunc;
|
||||||
|
|
||||||
|
struct OBSThemeMeta {
|
||||||
|
bool dark;
|
||||||
|
std::string parent;
|
||||||
|
std::string author;
|
||||||
|
};
|
||||||
|
|
||||||
class OBSApp : public QApplication {
|
class OBSApp : public QApplication {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -75,6 +81,7 @@ private:
|
||||||
std::string locale;
|
std::string locale;
|
||||||
std::string theme;
|
std::string theme;
|
||||||
QString defaultStyleSheet;
|
QString defaultStyleSheet;
|
||||||
|
OBSThemeMeta *themeMeta = nullptr;
|
||||||
bool themeDarkMode = true;
|
bool themeDarkMode = true;
|
||||||
ConfigFile globalConfig;
|
ConfigFile globalConfig;
|
||||||
TextLookup textLookup;
|
TextLookup textLookup;
|
||||||
|
@ -103,6 +110,7 @@ private:
|
||||||
QPalette defaultPalette;
|
QPalette defaultPalette;
|
||||||
|
|
||||||
void ParseExtraThemeData(const char *path);
|
void ParseExtraThemeData(const char *path);
|
||||||
|
static OBSThemeMeta *ParseThemeMeta(const char *path);
|
||||||
void AddExtraThemeColor(QPalette &pal, int group, const char *name,
|
void AddExtraThemeColor(QPalette &pal, int group, const char *name,
|
||||||
uint32_t color);
|
uint32_t color);
|
||||||
|
|
||||||
|
@ -130,6 +138,8 @@ public:
|
||||||
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(); }
|
||||||
|
std::string GetTheme(std::string name, std::string path);
|
||||||
|
std::string SetParentTheme(std::string name);
|
||||||
bool SetTheme(std::string name, std::string path = "");
|
bool SetTheme(std::string name, std::string path = "");
|
||||||
inline bool IsThemeDark() const { return themeDarkMode; };
|
inline bool IsThemeDark() const { return themeDarkMode; };
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue