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.
This commit is contained in:
Socapex 2015-02-17 02:45:34 -05:00 committed by jp9000
parent 5262fa31c0
commit 6a16778bc9
9 changed files with 154 additions and 7 deletions

View file

@ -217,6 +217,7 @@ Basic.Settings.Confirm="You have unsaved changes. Save changes?"
# basic mode 'general' settings
Basic.Settings.General="General"
Basic.Settings.General.Theme="Theme"
Basic.Settings.General.Language="Language"
# basic mode 'stream' settings

View file

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>770</width>
<width>895</width>
<height>602</height>
</rect>
</property>
@ -143,6 +143,16 @@
<item row="1" column="1">
<widget class="QComboBox" name="language"/>
</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>
</widget>
<widget class="QWidget" name="streamPage">
@ -2326,8 +2336,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>609</width>
<height>553</height>
<width>724</width>
<height>536</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
@ -2362,7 +2372,7 @@
<widget class="QLabel" name="label_35">
<property name="minimumSize">
<size>
<width>170</width>
<width>0</width>
<height>0</height>
</size>
</property>
@ -2409,7 +2419,7 @@
</property>
<property name="minimumSize">
<size>
<width>170</width>
<width>0</width>
<height>0</height>
</size>
</property>

View file

@ -1,5 +1,5 @@
<RCC>
<qresource prefix="res">
<qresource prefix="/res">
<file>images/configuration21_16.png</file>
<file>images/list_remove.png</file>
<file>images/add.png</file>
@ -10,7 +10,7 @@
<file>images/up.png</file>
<file>images/obs.png</file>
</qresource>
<qresource prefix="settings">
<qresource prefix="/settings">
<file>images/settings/advanced.png</file>
<file>images/settings/network.png</file>
<file>images/settings/video-display-3.png</file>

View file

@ -29,6 +29,7 @@
#include "qt-wrappers.hpp"
#include "obs-app.hpp"
#include "window-basic-main.hpp"
#include "window-basic-settings.hpp"
#include "window-license-agreement.hpp"
#include "crash-report.hpp"
#include "platform.hpp"
@ -233,6 +234,44 @@ bool OBSApp::InitLocale()
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)
: QApplication(argc, argv)
{}
@ -247,6 +286,8 @@ void OBSApp::AppInit()
throw "Failed to initialize global config";
if (!InitLocale())
throw "Failed to load locale";
if (!InitTheme())
throw "Failed to load theme";
}
const char *OBSApp::GetRenderModule() const

View file

@ -55,6 +55,7 @@ class OBSApp : public QApplication {
private:
std::string locale;
std::string theme;
ConfigFile globalConfig;
TextLookup textLookup;
QPointer<OBSMainWindow> mainWindow;
@ -62,6 +63,7 @@ private:
bool InitGlobalConfig();
bool InitGlobalConfigDefaults();
bool InitLocale();
bool InitTheme();
public:
OBSApp(int &argc, char **argv);
@ -78,6 +80,9 @@ public:
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 const char *GetString(const char *lookupVal) const

View file

@ -82,6 +82,7 @@ OBSBasic::OBSBasic(QWidget *parent)
ui (new Ui::OBSBasic)
{
ui->setupUi(this);
copyActionsDynamicProperties();
int width = config_get_int(App()->GlobalConfig(), "MainWindow", "cx");
@ -197,6 +198,26 @@ static obs_data_t *GenerateSaveData()
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()
{
VolControl *control;

View file

@ -180,6 +180,7 @@ private:
void AddSource(const char *id);
QMenu *CreateAddSourcePopupMenu();
void AddSourcePopupMenu(const QPoint &pos);
void copyActionsDynamicProperties();
public:
OBSScene GetCurrentScene();

View file

@ -1,5 +1,6 @@
/******************************************************************************
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
it under the terms of the GNU General Public License as published by
@ -23,6 +24,7 @@
#include <QMessageBox>
#include <QCloseEvent>
#include <QFileDialog>
#include <QDirIterator>
#include "obs-app.hpp"
#include "platform.hpp"
@ -134,6 +136,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
ui->setupUi(this);
HookWidget(ui->language, COMBO_CHANGED, GENERAL_CHANGED);
HookWidget(ui->theme, COMBO_CHANGED, GENERAL_CHANGED);
HookWidget(ui->outputMode, COMBO_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->streamType, COMBO_CHANGED, STREAM1_CHANGED);
HookWidget(ui->simpleOutputPath, EDIT_CHANGED, OUTPUTS_CHANGED);
@ -336,11 +339,52 @@ void OBSBasicSettings::LoadLanguageList()
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()
{
loading = true;
LoadLanguageList();
LoadThemeList();
loading = false;
}
@ -984,6 +1028,16 @@ void OBSBasicSettings::SaveGeneralSettings()
if (WidgetChanged(ui->language))
config_set_string(GetGlobalConfig(), "General", "Language",
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()
@ -1241,6 +1295,12 @@ void OBSBasicSettings::closeEvent(QCloseEvent *event)
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)
{
if (!checked)
@ -1276,6 +1336,8 @@ void OBSBasicSettings::on_buttonBox_clicked(QAbstractButton *button)
if (val == QDialogButtonBox::AcceptRole ||
val == QDialogButtonBox::RejectRole) {
if (val == QDialogButtonBox::RejectRole)
App()->SetTheme(savedTheme);
ClearChanged();
close();
}

View file

@ -1,5 +1,6 @@
/******************************************************************************
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
it under the terms of the GNU General Public License as published by
@ -20,6 +21,7 @@
#include <util/util.hpp>
#include <QDialog>
#include <memory>
#include <string>
#include <obs.h>
@ -45,6 +47,7 @@ private:
bool advancedChanged = false;
int pageIndex = 0;
bool loading = true;
std::string savedTheme;
OBSPropertiesView *streamProperties = nullptr;
OBSPropertiesView *streamEncoderProps = nullptr;
@ -104,6 +107,7 @@ private:
/* general */
void LoadLanguageList();
void LoadThemeList();
/* output */
void LoadSimpleOutputSettings();
@ -136,6 +140,8 @@ private:
void SaveSettings();
private slots:
void on_theme_activated(int idx);
void on_simpleOutUseBufsize_toggled(bool checked);
void on_simpleOutputVBitrate_valueChanged(int val);