UI: Implement theme selection option
OBS will offer the user a list of themes which are .qss files inside data/obs-studio/themes. If no theme is found in the configuration, it loads the default theme for the system.master
parent
5262fa31c0
commit
6a16778bc9
|
@ -217,6 +217,7 @@ Basic.Settings.Confirm="You have unsaved changes. Save changes?"
|
||||||
|
|
||||||
# basic mode 'general' settings
|
# basic mode 'general' settings
|
||||||
Basic.Settings.General="General"
|
Basic.Settings.General="General"
|
||||||
|
Basic.Settings.General.Theme="Theme"
|
||||||
Basic.Settings.General.Language="Language"
|
Basic.Settings.General.Language="Language"
|
||||||
|
|
||||||
# basic mode 'stream' settings
|
# basic mode 'stream' settings
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>770</width>
|
<width>895</width>
|
||||||
<height>602</height>
|
<height>602</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -143,6 +143,16 @@
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QComboBox" name="language"/>
|
<widget class="QComboBox" name="language"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_42">
|
||||||
|
<property name="text">
|
||||||
|
<string>Basic.Settings.General.Theme</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="theme"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="streamPage">
|
<widget class="QWidget" name="streamPage">
|
||||||
|
@ -2326,8 +2336,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>609</width>
|
<width>724</width>
|
||||||
<height>553</height>
|
<height>536</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||||
|
@ -2362,7 +2372,7 @@
|
||||||
<widget class="QLabel" name="label_35">
|
<widget class="QLabel" name="label_35">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>170</width>
|
<width>0</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -2409,7 +2419,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>170</width>
|
<width>0</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="res">
|
<qresource prefix="/res">
|
||||||
<file>images/configuration21_16.png</file>
|
<file>images/configuration21_16.png</file>
|
||||||
<file>images/list_remove.png</file>
|
<file>images/list_remove.png</file>
|
||||||
<file>images/add.png</file>
|
<file>images/add.png</file>
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
<file>images/up.png</file>
|
<file>images/up.png</file>
|
||||||
<file>images/obs.png</file>
|
<file>images/obs.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="settings">
|
<qresource prefix="/settings">
|
||||||
<file>images/settings/advanced.png</file>
|
<file>images/settings/advanced.png</file>
|
||||||
<file>images/settings/network.png</file>
|
<file>images/settings/network.png</file>
|
||||||
<file>images/settings/video-display-3.png</file>
|
<file>images/settings/video-display-3.png</file>
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "qt-wrappers.hpp"
|
#include "qt-wrappers.hpp"
|
||||||
#include "obs-app.hpp"
|
#include "obs-app.hpp"
|
||||||
#include "window-basic-main.hpp"
|
#include "window-basic-main.hpp"
|
||||||
|
#include "window-basic-settings.hpp"
|
||||||
#include "window-license-agreement.hpp"
|
#include "window-license-agreement.hpp"
|
||||||
#include "crash-report.hpp"
|
#include "crash-report.hpp"
|
||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
|
@ -233,6 +234,44 @@ bool OBSApp::InitLocale()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OBSApp::SetTheme(std::string name, std::string path)
|
||||||
|
{
|
||||||
|
theme = name;
|
||||||
|
|
||||||
|
/* Check user dir first, then preinstalled themes. */
|
||||||
|
if (path == "") {
|
||||||
|
char userDir[512];
|
||||||
|
name = "themes/" + name + ".qss";
|
||||||
|
string temp = "obs-studio/" + name;
|
||||||
|
int ret = os_get_config_path(userDir, sizeof(userDir),
|
||||||
|
temp.c_str());
|
||||||
|
|
||||||
|
if (ret > 0 && QFile::exists(userDir)) {
|
||||||
|
path = string(userDir);
|
||||||
|
} else if (!GetDataFilePath(name.c_str(), path)) {
|
||||||
|
OBSErrorBox(NULL, "Failed to find %s.", name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString mpath = QString("file:///") + path.c_str();
|
||||||
|
setStyleSheet(mpath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OBSApp::InitTheme()
|
||||||
|
{
|
||||||
|
const char *themeName = config_get_string(globalConfig, "General",
|
||||||
|
"Theme");
|
||||||
|
|
||||||
|
if (!themeName)
|
||||||
|
themeName = "Default";
|
||||||
|
|
||||||
|
stringstream t;
|
||||||
|
t << themeName;
|
||||||
|
return SetTheme(t.str());
|
||||||
|
}
|
||||||
|
|
||||||
OBSApp::OBSApp(int &argc, char **argv)
|
OBSApp::OBSApp(int &argc, char **argv)
|
||||||
: QApplication(argc, argv)
|
: QApplication(argc, argv)
|
||||||
{}
|
{}
|
||||||
|
@ -247,6 +286,8 @@ void OBSApp::AppInit()
|
||||||
throw "Failed to initialize global config";
|
throw "Failed to initialize global config";
|
||||||
if (!InitLocale())
|
if (!InitLocale())
|
||||||
throw "Failed to load locale";
|
throw "Failed to load locale";
|
||||||
|
if (!InitTheme())
|
||||||
|
throw "Failed to load theme";
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *OBSApp::GetRenderModule() const
|
const char *OBSApp::GetRenderModule() const
|
||||||
|
|
|
@ -55,6 +55,7 @@ class OBSApp : public QApplication {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string locale;
|
std::string locale;
|
||||||
|
std::string theme;
|
||||||
ConfigFile globalConfig;
|
ConfigFile globalConfig;
|
||||||
TextLookup textLookup;
|
TextLookup textLookup;
|
||||||
QPointer<OBSMainWindow> mainWindow;
|
QPointer<OBSMainWindow> mainWindow;
|
||||||
|
@ -62,6 +63,7 @@ private:
|
||||||
bool InitGlobalConfig();
|
bool InitGlobalConfig();
|
||||||
bool InitGlobalConfigDefaults();
|
bool InitGlobalConfigDefaults();
|
||||||
bool InitLocale();
|
bool InitLocale();
|
||||||
|
bool InitTheme();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OBSApp(int &argc, char **argv);
|
OBSApp(int &argc, char **argv);
|
||||||
|
@ -78,6 +80,9 @@ public:
|
||||||
return locale.c_str();
|
return locale.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
|
inline const char *GetString(const char *lookupVal) const
|
||||||
|
|
|
@ -82,6 +82,7 @@ OBSBasic::OBSBasic(QWidget *parent)
|
||||||
ui (new Ui::OBSBasic)
|
ui (new Ui::OBSBasic)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
copyActionsDynamicProperties();
|
||||||
|
|
||||||
int width = config_get_int(App()->GlobalConfig(), "MainWindow", "cx");
|
int width = config_get_int(App()->GlobalConfig(), "MainWindow", "cx");
|
||||||
|
|
||||||
|
@ -197,6 +198,26 @@ static obs_data_t *GenerateSaveData()
|
||||||
return saveData;
|
return saveData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OBSBasic::copyActionsDynamicProperties()
|
||||||
|
{
|
||||||
|
// Themes need the QAction dynamic properties
|
||||||
|
for (QAction *x : ui->scenesToolbar->actions()) {
|
||||||
|
QWidget* temp = ui->scenesToolbar->widgetForAction(x);
|
||||||
|
|
||||||
|
for (QByteArray &y : x->dynamicPropertyNames()) {
|
||||||
|
temp->setProperty(y, x->property(y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (QAction *x : ui->sourcesToolbar->actions()) {
|
||||||
|
QWidget* temp = ui->sourcesToolbar->widgetForAction(x);
|
||||||
|
|
||||||
|
for (QByteArray &y : x->dynamicPropertyNames()) {
|
||||||
|
temp->setProperty(y, x->property(y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OBSBasic::ClearVolumeControls()
|
void OBSBasic::ClearVolumeControls()
|
||||||
{
|
{
|
||||||
VolControl *control;
|
VolControl *control;
|
||||||
|
|
|
@ -180,6 +180,7 @@ private:
|
||||||
void AddSource(const char *id);
|
void AddSource(const char *id);
|
||||||
QMenu *CreateAddSourcePopupMenu();
|
QMenu *CreateAddSourcePopupMenu();
|
||||||
void AddSourcePopupMenu(const QPoint &pos);
|
void AddSourcePopupMenu(const QPoint &pos);
|
||||||
|
void copyActionsDynamicProperties();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OBSScene GetCurrentScene();
|
OBSScene GetCurrentScene();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
|
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
|
||||||
|
Philippe Groarke <philippe.groarke@gmail.com>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QDirIterator>
|
||||||
|
|
||||||
#include "obs-app.hpp"
|
#include "obs-app.hpp"
|
||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
|
@ -134,6 +136,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
HookWidget(ui->language, COMBO_CHANGED, GENERAL_CHANGED);
|
HookWidget(ui->language, COMBO_CHANGED, GENERAL_CHANGED);
|
||||||
|
HookWidget(ui->theme, COMBO_CHANGED, GENERAL_CHANGED);
|
||||||
HookWidget(ui->outputMode, COMBO_CHANGED, OUTPUTS_CHANGED);
|
HookWidget(ui->outputMode, COMBO_CHANGED, OUTPUTS_CHANGED);
|
||||||
HookWidget(ui->streamType, COMBO_CHANGED, STREAM1_CHANGED);
|
HookWidget(ui->streamType, COMBO_CHANGED, STREAM1_CHANGED);
|
||||||
HookWidget(ui->simpleOutputPath, EDIT_CHANGED, OUTPUTS_CHANGED);
|
HookWidget(ui->simpleOutputPath, EDIT_CHANGED, OUTPUTS_CHANGED);
|
||||||
|
@ -336,11 +339,52 @@ void OBSBasicSettings::LoadLanguageList()
|
||||||
ui->language->model()->sort(0);
|
ui->language->model()->sort(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OBSBasicSettings::LoadThemeList()
|
||||||
|
{
|
||||||
|
/* Save theme if user presses Cancel */
|
||||||
|
savedTheme = string(App()->GetTheme());
|
||||||
|
|
||||||
|
ui->theme->clear();
|
||||||
|
QSet<QString> uniqueSet;
|
||||||
|
string themeDir;
|
||||||
|
char userThemeDir[512];
|
||||||
|
int ret = os_get_config_path(userThemeDir, sizeof(userThemeDir),
|
||||||
|
"obs-studio/themes/");
|
||||||
|
GetDataFilePath("themes/", themeDir);
|
||||||
|
|
||||||
|
/* Check user dir first. */
|
||||||
|
if (ret > 0) {
|
||||||
|
QDirIterator it(QString(userThemeDir), QStringList() << "*.qss",
|
||||||
|
QDir::Files);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
QString name = it.fileName().section(".",0,0);
|
||||||
|
ui->theme->addItem(name);
|
||||||
|
uniqueSet.insert(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check shipped themes. */
|
||||||
|
QDirIterator uIt(QString(themeDir.c_str()), QStringList() << "*.qss",
|
||||||
|
QDir::Files);
|
||||||
|
while (uIt.hasNext()) {
|
||||||
|
uIt.next();
|
||||||
|
QString name = uIt.fileName().section(".",0,0);
|
||||||
|
if (!uniqueSet.contains(name))
|
||||||
|
ui->theme->addItem(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int idx = ui->theme->findText(App()->GetTheme());
|
||||||
|
if (idx != -1)
|
||||||
|
ui->theme->setCurrentIndex(idx);
|
||||||
|
}
|
||||||
|
|
||||||
void OBSBasicSettings::LoadGeneralSettings()
|
void OBSBasicSettings::LoadGeneralSettings()
|
||||||
{
|
{
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
LoadLanguageList();
|
LoadLanguageList();
|
||||||
|
LoadThemeList();
|
||||||
|
|
||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
|
@ -984,6 +1028,16 @@ void OBSBasicSettings::SaveGeneralSettings()
|
||||||
if (WidgetChanged(ui->language))
|
if (WidgetChanged(ui->language))
|
||||||
config_set_string(GetGlobalConfig(), "General", "Language",
|
config_set_string(GetGlobalConfig(), "General", "Language",
|
||||||
language.c_str());
|
language.c_str());
|
||||||
|
|
||||||
|
int themeIndex = ui->theme->currentIndex();
|
||||||
|
QString themeData = ui->theme->itemText(themeIndex);
|
||||||
|
string theme = themeData.toStdString();
|
||||||
|
|
||||||
|
if (WidgetChanged(ui->theme)) {
|
||||||
|
config_set_string(GetGlobalConfig(), "General", "Theme",
|
||||||
|
theme.c_str());
|
||||||
|
App()->SetTheme(theme);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OBSBasicSettings::SaveStream1Settings()
|
void OBSBasicSettings::SaveStream1Settings()
|
||||||
|
@ -1241,6 +1295,12 @@ void OBSBasicSettings::closeEvent(QCloseEvent *event)
|
||||||
event->ignore();
|
event->ignore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OBSBasicSettings::on_theme_activated(int idx)
|
||||||
|
{
|
||||||
|
string currT = ui->theme->itemText(idx).toStdString();
|
||||||
|
App()->SetTheme(currT);
|
||||||
|
}
|
||||||
|
|
||||||
void OBSBasicSettings::on_simpleOutUseBufsize_toggled(bool checked)
|
void OBSBasicSettings::on_simpleOutUseBufsize_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (!checked)
|
if (!checked)
|
||||||
|
@ -1276,6 +1336,8 @@ void OBSBasicSettings::on_buttonBox_clicked(QAbstractButton *button)
|
||||||
|
|
||||||
if (val == QDialogButtonBox::AcceptRole ||
|
if (val == QDialogButtonBox::AcceptRole ||
|
||||||
val == QDialogButtonBox::RejectRole) {
|
val == QDialogButtonBox::RejectRole) {
|
||||||
|
if (val == QDialogButtonBox::RejectRole)
|
||||||
|
App()->SetTheme(savedTheme);
|
||||||
ClearChanged();
|
ClearChanged();
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
|
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
|
||||||
|
Philippe Groarke <philippe.groarke@gmail.com>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
#include <util/util.hpp>
|
#include <util/util.hpp>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <obs.h>
|
#include <obs.h>
|
||||||
|
|
||||||
|
@ -45,6 +47,7 @@ private:
|
||||||
bool advancedChanged = false;
|
bool advancedChanged = false;
|
||||||
int pageIndex = 0;
|
int pageIndex = 0;
|
||||||
bool loading = true;
|
bool loading = true;
|
||||||
|
std::string savedTheme;
|
||||||
|
|
||||||
OBSPropertiesView *streamProperties = nullptr;
|
OBSPropertiesView *streamProperties = nullptr;
|
||||||
OBSPropertiesView *streamEncoderProps = nullptr;
|
OBSPropertiesView *streamEncoderProps = nullptr;
|
||||||
|
@ -104,6 +107,7 @@ private:
|
||||||
|
|
||||||
/* general */
|
/* general */
|
||||||
void LoadLanguageList();
|
void LoadLanguageList();
|
||||||
|
void LoadThemeList();
|
||||||
|
|
||||||
/* output */
|
/* output */
|
||||||
void LoadSimpleOutputSettings();
|
void LoadSimpleOutputSettings();
|
||||||
|
@ -136,6 +140,8 @@ private:
|
||||||
void SaveSettings();
|
void SaveSettings();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void on_theme_activated(int idx);
|
||||||
|
|
||||||
void on_simpleOutUseBufsize_toggled(bool checked);
|
void on_simpleOutUseBufsize_toggled(bool checked);
|
||||||
void on_simpleOutputVBitrate_valueChanged(int val);
|
void on_simpleOutputVBitrate_valueChanged(int val);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue