Merge pull request #378 from Socapex/darkTheme
UI: Implement theme selection option UI: Change "Language:" to "Language" (consistency) UI: Make "output mode" label disabled if active UI: Give "advanced" section icon a white border UI: Add dark theme (Manually merged) Closes Pull Request #378
@ -217,7 +217,8 @@ Basic.Settings.Confirm="You have unsaved changes. Save changes?"
|
||||
|
||||
# basic mode 'general' settings
|
||||
Basic.Settings.General="General"
|
||||
Basic.Settings.General.Language="Language:"
|
||||
Basic.Settings.General.Theme="Theme"
|
||||
Basic.Settings.General.Language="Language"
|
||||
|
||||
# basic mode 'stream' settings
|
||||
Basic.Settings.Stream="Stream"
|
||||
|
457
obs/data/themes/Dark.qss
Normal file
@ -0,0 +1,457 @@
|
||||
/******************************************************************************/
|
||||
/* Copyright (C) 2014-2015 by 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 */
|
||||
/* 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/>. */
|
||||
/******************************************************************************/
|
||||
|
||||
/* Colors */
|
||||
|
||||
/* rgb(225,224,225); /* veryLight */
|
||||
/* rgb(200,199,200); /* lighter */
|
||||
/* rgb(122,121,122); /* light */
|
||||
/* rgb(88,87,88); /* kindaDark */
|
||||
/* rgb(58,57,58); /* dark */
|
||||
/* rgb(31,30,31); /* veryDark */
|
||||
/* rgb(11,10,11); /* veryVeryDark */
|
||||
/* rgb(42,130,218); /* blue */
|
||||
|
||||
|
||||
/* General style, we override only what is needed. */
|
||||
QWidget {
|
||||
background-color: rgb(58,57,58); /* dark */
|
||||
alternate-background-color: rgb(31,30,31); /* veryDark */
|
||||
color: rgb(225,224,225); /* veryLight */
|
||||
selection-background-color: rgb(42,130,218); /* blue */
|
||||
selection-color: black;
|
||||
}
|
||||
|
||||
|
||||
/* Misc */
|
||||
|
||||
QWidget::disabled {
|
||||
color: 2px solid rgb(200,199,200); /* lighter */
|
||||
}
|
||||
|
||||
QAbstractItemView {
|
||||
background-color: rgb(31,30,31); /* veryDark */
|
||||
}
|
||||
|
||||
QToolTip {
|
||||
background-color: rgb(31,30,31); /* veryDark */
|
||||
color: rgb(205,205,205);
|
||||
}
|
||||
|
||||
QMenuBar::item {
|
||||
background-color: rgb(58,57,58); /* dark */
|
||||
}
|
||||
|
||||
|
||||
/* Group Box */
|
||||
|
||||
QGroupBox {
|
||||
border: 1px solid rgb(31,30,31); /* veryDark */;
|
||||
border-radius: 5px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
|
||||
/* ScrollBars */
|
||||
|
||||
::corner {
|
||||
background-color: rgb(58,57,58); /* dark */
|
||||
border: none;
|
||||
}
|
||||
|
||||
QScrollBar:vertical {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
|
||||
stop: 0 rgb(31,30,31), /* veryDark */
|
||||
stop: 0.75 rgb(54, 53, 54),
|
||||
stop: 1 rgb(58,57,58)); /* dark */
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
QScrollBar::handle:vertical {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
|
||||
stop: 0 rgb(122,121,122), /* light */
|
||||
stop: 0.25 rgb(100, 99, 100),
|
||||
stop: 1 rgb(88,87,88)); /* kindaDark */
|
||||
min-height: 20px;
|
||||
margin: 2px;
|
||||
border-radius: 5px;
|
||||
border-width: 1px;
|
||||
border: 1px solid rgb(31,30,31); /* veryDark */
|
||||
}
|
||||
|
||||
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
|
||||
border: none;
|
||||
background: none;
|
||||
color: none;
|
||||
}
|
||||
|
||||
QScrollBar:horizontal {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(31,30,31), /* veryDark */
|
||||
stop: 0.75 rgb(54, 53, 54),
|
||||
stop: 1 rgb(58,57,58)); /* dark */
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
QScrollBar::handle:horizontal {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(122,121,122), /* light */
|
||||
stop: 0.25 rgb(100, 99, 100),
|
||||
stop: 1 rgb(88,87,88)); /* kindaDark */
|
||||
min-width: 20px;
|
||||
margin: 2px;
|
||||
border-radius: 5px;
|
||||
border-width: 1px;
|
||||
border: 1px solid rgb(31,30,31); /* veryDark */
|
||||
}
|
||||
|
||||
QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal {
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
QScrollBar::left-arrow:horizontal, QScrollBar::right-arrow:horizontal, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
|
||||
border: none;
|
||||
background: none;
|
||||
color: none;
|
||||
}
|
||||
|
||||
|
||||
/* Scenes and Sources toolbar */
|
||||
|
||||
QToolBar {
|
||||
background-color: rgb(58,57,58); /* dark */
|
||||
border: none;
|
||||
}
|
||||
|
||||
QToolButton:hover {
|
||||
background-color: rgb(122,121,122); /* light */
|
||||
border-radius: none;
|
||||
}
|
||||
|
||||
QToolButton:pressed {
|
||||
background-color: rgb(31,30,31); /* veryDark */
|
||||
border-radius: none;
|
||||
}
|
||||
|
||||
* [themeID="addIconSmall"] {
|
||||
qproperty-icon: url(./Dark/plus.png);
|
||||
}
|
||||
|
||||
* [themeID="removeIconSmall"] {
|
||||
qproperty-icon: url(./Dark/minus.png);
|
||||
}
|
||||
|
||||
* [themeID="propertiesIconSmall"] {
|
||||
qproperty-icon: url(./Dark/cogwheel.png);
|
||||
}
|
||||
|
||||
* [themeID="configIconSmall"] {
|
||||
qproperty-icon: url(./Dark/cogwheel.png);
|
||||
}
|
||||
|
||||
* [themeID="upArrowIconSmall"] {
|
||||
qproperty-icon: url(./Dark/up_arrow.png);
|
||||
}
|
||||
|
||||
* [themeID="downArrowIconSmall"] {
|
||||
qproperty-icon: url(./Dark/down_arrow.png);
|
||||
}
|
||||
|
||||
|
||||
/* Tab Widget */
|
||||
|
||||
QTabWidget::pane { /* The tab widget frame */
|
||||
border-top: 1px solid rgb(31,30,31); /* veryDark */
|
||||
}
|
||||
|
||||
QTabWidget::tab-bar {
|
||||
alignment: center;
|
||||
}
|
||||
|
||||
QTabBar::tab {
|
||||
background-color: rgb(88,87,88); /* kindaDark */
|
||||
border: none;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
min-width: 8ex;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
background-color: rgb(31,30,31); /* veryDark */
|
||||
}
|
||||
|
||||
QTabBar::tab:hover {
|
||||
background-color: rgb(122,121,122); /* light */
|
||||
}
|
||||
|
||||
QTabBar::tab:pressed {
|
||||
background-color: rgb(31,30,31); /* veryDark */
|
||||
}
|
||||
|
||||
|
||||
/* ComboBox */
|
||||
|
||||
QComboBox {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(86,85,86),
|
||||
stop: 0.1 rgb(82,81,82),
|
||||
stop: 0.5 rgb(78,77,78),
|
||||
stop: 0.9 rgb(74,73,74),
|
||||
stop: 1 rgb(70,69,70));
|
||||
border-style: solid;
|
||||
border: 1px;
|
||||
border-radius: 3px;
|
||||
border-color: rgb(31,30,31); /* veryDark */
|
||||
padding: 2px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
QComboBox::drop-down {
|
||||
border:none;
|
||||
border-left: 1px solid rgba(31,30,31,155); /* veryDark */
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
QComboBox::down-arrow {
|
||||
qproperty-alignment: AlignTop;
|
||||
image: url(./Dark/updown.png);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
QComboBox:on {
|
||||
background-color: rgb(31,30,31); /* veryDark */
|
||||
}
|
||||
|
||||
QComboBox:editable {
|
||||
border-top-left-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
|
||||
QComboBox::drop-down:editable {
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
|
||||
QComboBox::down-arrow:editable {
|
||||
qproperty-alignment: AlignTop;
|
||||
image: url(./Dark/down_arrow.png);
|
||||
width: 8%;
|
||||
}
|
||||
|
||||
|
||||
/* Textedits etc */
|
||||
|
||||
QLineEdit, QTextEdit, QPlainTextEdit {
|
||||
background-color: rgb(31,30,31); /* veryDark */
|
||||
border: none;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
|
||||
/* Spinbox and doubleSpinbox */
|
||||
|
||||
QSpinBox, QDoubleSpinBox {
|
||||
background-color: rgb(31,30,31); /* veryDark */
|
||||
border: none;
|
||||
padding-left: 2px;
|
||||
padding-right: 15px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
QSpinBox::up-button, QDoubleSpinBox::up-button {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top right; /* position at the top right corner */
|
||||
|
||||
background-color: rgb(88,87,88); /* kindaDark */
|
||||
border: 1px solid rgb(31,30,31); /* veryDark */
|
||||
border-radius: 3px;
|
||||
border-width: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
QSpinBox::down-button, QDoubleSpinBox::down-button {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: bottom right; /* position at the top right corner */
|
||||
background-color: rgb(88,87,88); /* kindaDark */
|
||||
border: 1px solid rgb(31,30,31); /* veryDark */
|
||||
border-radius: 3px;
|
||||
border-width: 0;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
QSpinBox::up-button:hover, QSpinBox::down-button:hover, QDoubleSpinBox::up-button:hover, QDoubleSpinBox::down-button:hover {
|
||||
background-color: rgb(122,121,122); /* light */
|
||||
}
|
||||
|
||||
QSpinBox::up-button:pressed, QSpinBox::down-button:pressed, QDoubleSpinBox::up-button:pressed, QDoubleSpinBox::down-button:pressed {
|
||||
background-color: rgb(58,57,58); /* dark */
|
||||
}
|
||||
|
||||
QSpinBox::up-button:disabled, QSpinBox::up-button:off, QSpinBox::down-button:disabled, QSpinBox::down-button:off {
|
||||
background-color: rgb(58,57,58); /* dark */
|
||||
}
|
||||
|
||||
QDoubleSpinBox::up-button:disabled, QDoubleSpinBox::up-button:off, QDoubleSpinBox::down-button:disabled, QDoubleSpinBox::down-button:off {
|
||||
background-color: rgb(58,57,58); /* dark */
|
||||
}
|
||||
|
||||
QSpinBox::up-arrow, QDoubleSpinBox::up-arrow {
|
||||
image: url(./Dark/up_arrow.png);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
QSpinBox::down-arrow, QDoubleSpinBox::down-arrow {
|
||||
image: url(./Dark/down_arrow.png);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
/* Buttons */
|
||||
|
||||
QPushButton {
|
||||
color: rgb(225,224,225); /* veryLight */
|
||||
background-color: rgb(88,87,88); /* kindaDark */
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
padding: 4px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
QPushButton::flat {
|
||||
background-color: rgb(58,57,58); /* dark */
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
background-color: rgb(122,121,122); /* light */
|
||||
}
|
||||
|
||||
QPushButton:pressed {
|
||||
background-color: rgb(31,30,31); /* veryDark */
|
||||
}
|
||||
|
||||
|
||||
/* Sliders */
|
||||
|
||||
QSlider::groove:horizontal {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(31,30,31), /* veryDark */
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
height: 4px;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(240,239,240), /* lighter */
|
||||
stop: 0.25 rgb(200,199,200),
|
||||
stop: 1 rgb(162,161,162)); /* light */
|
||||
border: 1px solid rgb(58,57,58); /* dark */
|
||||
border-radius: 3px;
|
||||
height: 10px;
|
||||
width: 18px;
|
||||
margin: -3px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:pressed {
|
||||
background-color: QLinearGradient(x1: 0, y1: 1, x2: 0, y2: 0,
|
||||
stop: 0 rgb(240,239,240), /* lighter */
|
||||
stop: 0.25 rgb(200,199,200),
|
||||
stop: 1 rgb(162,161,162)); /* light */
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal:disabled {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(31,30,31), /* veryDark */
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::groove:vertical {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
|
||||
stop: 0 rgb(31,30,31), /* veryDark */
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
width: 4px;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::handle:vertical {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
|
||||
stop: 0 rgb(240,239,240), /* lighter */
|
||||
stop: 0.25 rgb(200,199,200),
|
||||
stop: 1 rgb(162,161,162)); /* light */
|
||||
border: 1px solid rgb(58,57,58); /* dark */
|
||||
border-radius: 4px;
|
||||
width: 10px;
|
||||
height: 18px;
|
||||
margin: -3px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */
|
||||
}
|
||||
|
||||
QSlider::handle:vertical:pressed {
|
||||
background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0,
|
||||
stop: 0 rgb(240,239,240), /* lighter */
|
||||
stop: 0.25 rgb(200,199,200),
|
||||
stop: 1 rgb(162,161,162)); /* light */
|
||||
}
|
||||
|
||||
QSlider::sub-page:vertical:disabled {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
|
||||
stop: 0 rgb(31,30,31), /* veryDark */
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::handle:hover {
|
||||
background-color: rgb(200,199,200); /* veryLight */
|
||||
}
|
||||
|
||||
QSlider::sub-page {
|
||||
background-color: rgb(42,130,218); /* blue */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::handle:disabled {
|
||||
background-color: rgb(122,121,122); /* light */
|
||||
}
|
||||
|
||||
|
||||
/* Volume Control */
|
||||
|
||||
VolumeMeter {
|
||||
qproperty-bkColor: rgb(31,30,31); /* veryDark */
|
||||
qproperty-magColor:;
|
||||
qproperty-peakColor:;
|
||||
qproperty-peakHoldColor: rgb(225,224,225); /* veryLight */
|
||||
}
|
BIN
obs/data/themes/Dark/cogwheel.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
obs/data/themes/Dark/down_arrow.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
obs/data/themes/Dark/minus.png
Normal file
After Width: | Height: | Size: 992 B |
BIN
obs/data/themes/Dark/plus.png
Normal file
After Width: | Height: | Size: 1002 B |
BIN
obs/data/themes/Dark/up_arrow.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
obs/data/themes/Dark/updown.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
46
obs/data/themes/Default.qss
Normal file
@ -0,0 +1,46 @@
|
||||
/* Intentionnally left blank */
|
||||
/* Themes are created using Qt CSS, you can visit */
|
||||
/* http://doc.qt.io/qt-5/stylesheet-reference.html and */
|
||||
/* http://doc.qt.io/qt-5/stylesheet-examples.html for examples. */
|
||||
|
||||
/* OBS will use the theme filename for the settings. */
|
||||
/* You can ship images using relative paths in qss. */
|
||||
/* Dark Theme is a good place to start if you need */
|
||||
/* a template. */
|
||||
|
||||
|
||||
/* We need to set back the icons, or the preview wont stick. */
|
||||
|
||||
* [themeID="addIconSmall"] {
|
||||
qproperty-icon: url(:/res/images/add.png);
|
||||
}
|
||||
|
||||
* [themeID="removeIconSmall"] {
|
||||
qproperty-icon: url(:/res/images/list_remove.png);
|
||||
}
|
||||
|
||||
* [themeID="propertiesIconSmall"] {
|
||||
qproperty-icon: url(:/res/images/properties.png);
|
||||
}
|
||||
|
||||
* [themeID="configIconSmall"] {
|
||||
qproperty-icon: url(:/res/images/configuration21_16.png);
|
||||
}
|
||||
|
||||
* [themeID="upArrowIconSmall"] {
|
||||
qproperty-icon: url(:/res/images/up.png);
|
||||
}
|
||||
|
||||
* [themeID="downArrowIconSmall"] {
|
||||
qproperty-icon: url(:/res/images/down.png);
|
||||
}
|
||||
|
||||
|
||||
/* Volume Control */
|
||||
|
||||
VolumeMeter {
|
||||
qproperty-bkColor: rgb(221, 221, 221);
|
||||
qproperty-magColor: rgb(32, 125, 23);
|
||||
qproperty-peakColor: rgb(62, 241, 43);
|
||||
qproperty-peakHoldColor: rgb(0, 0, 0);
|
||||
}
|
@ -220,6 +220,9 @@
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">configIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@ -594,6 +597,9 @@
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">addIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAddSource">
|
||||
<property name="icon">
|
||||
@ -603,6 +609,9 @@
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">addIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRemoveScene">
|
||||
<property name="icon">
|
||||
@ -618,6 +627,9 @@
|
||||
<property name="shortcutContext">
|
||||
<enum>Qt::WidgetWithChildrenShortcut</enum>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">removeIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRemoveSource">
|
||||
<property name="icon">
|
||||
@ -633,6 +645,9 @@
|
||||
<property name="shortcutContext">
|
||||
<enum>Qt::WidgetWithChildrenShortcut</enum>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">removeIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSceneProperties">
|
||||
<property name="enabled">
|
||||
@ -645,6 +660,9 @@
|
||||
<property name="text">
|
||||
<string>Properties</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">propertiesIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSourceProperties">
|
||||
<property name="enabled">
|
||||
@ -657,6 +675,9 @@
|
||||
<property name="text">
|
||||
<string>Properties</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">propertiesIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSceneUp">
|
||||
<property name="enabled">
|
||||
@ -669,6 +690,9 @@
|
||||
<property name="text">
|
||||
<string>Basic.Main.MoveUp</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">upArrowIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSourceUp">
|
||||
<property name="enabled">
|
||||
@ -681,6 +705,9 @@
|
||||
<property name="text">
|
||||
<string>MoveUp</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">upArrowIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSceneDown">
|
||||
<property name="enabled">
|
||||
@ -693,6 +720,9 @@
|
||||
<property name="text">
|
||||
<string>Basic.Main.MoveDown</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">downArrowIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSourceDown">
|
||||
<property name="enabled">
|
||||
@ -705,6 +735,9 @@
|
||||
<property name="text">
|
||||
<string>MoveDown</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">downArrowIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_New">
|
||||
<property name="text">
|
||||
|
@ -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">
|
||||
@ -271,7 +281,7 @@
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<widget class="QLabel" name="outputModeLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>170</width>
|
||||
@ -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>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 2.4 KiB |
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -180,6 +180,7 @@ private:
|
||||
void AddSource(const char *id);
|
||||
QMenu *CreateAddSourcePopupMenu();
|
||||
void AddSourcePopupMenu(const QPoint &pos);
|
||||
void copyActionsDynamicProperties();
|
||||
|
||||
public:
|
||||
OBSScene GetCurrentScene();
|
||||
|
@ -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;
|
||||
}
|
||||
@ -831,6 +875,7 @@ void OBSBasicSettings::LoadOutputSettings()
|
||||
|
||||
if (video_output_active(obs_get_video())) {
|
||||
ui->outputMode->setEnabled(false);
|
||||
ui->outputModeLabel->setEnabled(false);
|
||||
ui->advOutTopContainer->setEnabled(false);
|
||||
ui->advOutRecTopContainer->setEnabled(false);
|
||||
ui->advOutRecTypeContainer->setEnabled(false);
|
||||
@ -983,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()
|
||||
@ -1240,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)
|
||||
@ -1275,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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|