frontend: Add new appearance options
This commit is contained in:
parent
cce189011e
commit
c0c77071b5
@ -296,6 +296,9 @@ void OBSApp::InitUserConfigDefaults()
|
|||||||
config_set_default_bool(userConfig, "BasicWindow", "MultiviewDrawAreas", true);
|
config_set_default_bool(userConfig, "BasicWindow", "MultiviewDrawAreas", true);
|
||||||
|
|
||||||
config_set_default_bool(userConfig, "BasicWindow", "MediaControlsCountdownTimer", true);
|
config_set_default_bool(userConfig, "BasicWindow", "MediaControlsCountdownTimer", true);
|
||||||
|
|
||||||
|
config_set_default_int(userConfig, "Appearance", "FontScale", 10);
|
||||||
|
config_set_default_int(userConfig, "Appearance", "Density", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool do_mkdir(const char *path)
|
static bool do_mkdir(const char *path)
|
||||||
|
@ -204,7 +204,7 @@ static QColor ParseColor(CFParser &cfp)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseCalc(CFParser &cfp, QStringList &calc, vector<OBSThemeVariable> &vars)
|
static bool ParseMath(CFParser &cfp, QStringList &values, vector<OBSThemeVariable> &vars)
|
||||||
{
|
{
|
||||||
int ret = cf_next_token_should_be(cfp, "(", ";", nullptr);
|
int ret = cf_next_token_should_be(cfp, "(", ";", nullptr);
|
||||||
if (ret != PARSE_SUCCESS)
|
if (ret != PARSE_SUCCESS)
|
||||||
@ -216,36 +216,44 @@ static bool ParseCalc(CFParser &cfp, QStringList &calc, vector<OBSThemeVariable>
|
|||||||
if (cf_token_is(cfp, ";"))
|
if (cf_token_is(cfp, ";"))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (cf_token_is(cfp, "calc")) {
|
if (cf_token_is(cfp, "calc") || cf_token_is(cfp, "max") || cf_token_is(cfp, "min")) {
|
||||||
/* Internal calc's do not have proper names.
|
/* Internal math operations do not have proper names.
|
||||||
* They are anonymous variables */
|
* They are anonymous variables */
|
||||||
OBSThemeVariable var;
|
OBSThemeVariable var;
|
||||||
QStringList subcalc;
|
QStringList subvalues;
|
||||||
|
|
||||||
var.name = QString("__unnamed_%1").arg(QRandomGenerator::global()->generate64());
|
var.name = QString("__unnamed_%1").arg(QRandomGenerator::global()->generate64());
|
||||||
|
|
||||||
if (!ParseCalc(cfp, subcalc, vars))
|
OBSThemeVariable::VariableType varType;
|
||||||
|
if (cf_token_is(cfp, "calc"))
|
||||||
|
varType = OBSThemeVariable::Calc;
|
||||||
|
else if (cf_token_is(cfp, "max"))
|
||||||
|
varType = OBSThemeVariable::Max;
|
||||||
|
else if (cf_token_is(cfp, "min"))
|
||||||
|
varType = OBSThemeVariable::Min;
|
||||||
|
|
||||||
|
if (!ParseMath(cfp, subvalues, vars))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var.type = OBSThemeVariable::Calc;
|
var.type = varType;
|
||||||
var.value = subcalc;
|
var.value = subvalues;
|
||||||
calc << var.name;
|
values << var.name;
|
||||||
vars.push_back(std::move(var));
|
vars.push_back(std::move(var));
|
||||||
} else if (cf_token_is(cfp, "var")) {
|
} else if (cf_token_is(cfp, "var")) {
|
||||||
QString value;
|
QString value;
|
||||||
if (!ParseVarName(cfp, value))
|
if (!ParseVarName(cfp, value))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
calc << value;
|
values << value;
|
||||||
} else {
|
} else {
|
||||||
calc << QString::fromUtf8(cfp->cur_token->str.array, cfp->cur_token->str.len);
|
values << QString::fromUtf8(cfp->cur_token->str.array, cfp->cur_token->str.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cf_next_token(cfp))
|
if (!cf_next_token(cfp))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !calc.isEmpty();
|
return !values.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
static vector<OBSThemeVariable> ParseThemeVariables(const char *themeData)
|
static vector<OBSThemeVariable> ParseThemeVariables(const char *themeData)
|
||||||
@ -316,6 +324,11 @@ static vector<OBSThemeVariable> ParseThemeVariables(const char *themeData)
|
|||||||
if (!cf_next_token(cfp))
|
if (!cf_next_token(cfp))
|
||||||
return vars;
|
return vars;
|
||||||
|
|
||||||
|
/* Special values passed to the theme by OBS are prefixed with 'obs', so we
|
||||||
|
* prevent theme variables from using it as a prefix. */
|
||||||
|
if (key.startsWith("obs"))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (cfp->cur_token->type == CFTOKEN_NUM) {
|
if (cfp->cur_token->type == CFTOKEN_NUM) {
|
||||||
const char *ch = cfp->cur_token->str.array;
|
const char *ch = cfp->cur_token->str.array;
|
||||||
const char *end = ch + cfp->cur_token->str.len;
|
const char *end = ch + cfp->cur_token->str.len;
|
||||||
@ -348,14 +361,20 @@ static vector<OBSThemeVariable> ParseThemeVariables(const char *themeData)
|
|||||||
|
|
||||||
var.value = value;
|
var.value = value;
|
||||||
var.type = OBSThemeVariable::Alias;
|
var.type = OBSThemeVariable::Alias;
|
||||||
} else if (cf_token_is(cfp, "calc")) {
|
} else if (cf_token_is(cfp, "calc") || cf_token_is(cfp, "max") || cf_token_is(cfp, "min")) {
|
||||||
QStringList calc;
|
QStringList values;
|
||||||
|
|
||||||
if (!ParseCalc(cfp, calc, vars))
|
if (cf_token_is(cfp, "calc"))
|
||||||
|
var.type = OBSThemeVariable::Calc;
|
||||||
|
else if (cf_token_is(cfp, "max"))
|
||||||
|
var.type = OBSThemeVariable::Max;
|
||||||
|
else if (cf_token_is(cfp, "min"))
|
||||||
|
var.type = OBSThemeVariable::Min;
|
||||||
|
|
||||||
|
if (!ParseMath(cfp, values, vars))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var.type = OBSThemeVariable::Calc;
|
var.value = values;
|
||||||
var.value = calc;
|
|
||||||
} else {
|
} else {
|
||||||
var.type = OBSThemeVariable::String;
|
var.type = OBSThemeVariable::String;
|
||||||
BPtr strVal = cf_literal_to_str(cfp->cur_token->str.array, cfp->cur_token->str.len);
|
BPtr strVal = cf_literal_to_str(cfp->cur_token->str.array, cfp->cur_token->str.len);
|
||||||
@ -367,8 +386,9 @@ static vector<OBSThemeVariable> ParseThemeVariables(const char *themeData)
|
|||||||
|
|
||||||
if (cf_token_is(cfp, "!") &&
|
if (cf_token_is(cfp, "!") &&
|
||||||
cf_next_token_should_be(cfp, "editable", nullptr, nullptr) == PARSE_SUCCESS) {
|
cf_next_token_should_be(cfp, "editable", nullptr, nullptr) == PARSE_SUCCESS) {
|
||||||
if (var.type == OBSThemeVariable::Calc || var.type == OBSThemeVariable::Alias) {
|
if (var.type == OBSThemeVariable::Calc || var.type == OBSThemeVariable::Max ||
|
||||||
blog(LOG_WARNING, "Variable of calc/alias type cannot be editable: %s",
|
var.type == OBSThemeVariable::Min || var.type == OBSThemeVariable::Alias) {
|
||||||
|
blog(LOG_WARNING, "Math or alias variable type cannot be editable: %s",
|
||||||
QT_TO_UTF8(var.name));
|
QT_TO_UTF8(var.name));
|
||||||
} else {
|
} else {
|
||||||
var.editable = true;
|
var.editable = true;
|
||||||
@ -496,10 +516,10 @@ static bool ResolveVariable(const QHash<QString, OBSThemeVariable> &vars, OBSThe
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString EvalCalc(const QHash<QString, OBSThemeVariable> &vars, const OBSThemeVariable &var,
|
static QString EvalMath(const QHash<QString, OBSThemeVariable> &vars, const OBSThemeVariable &var,
|
||||||
const int recursion = 0);
|
const OBSThemeVariable::VariableType type, const int recursion = 0);
|
||||||
|
|
||||||
static OBSThemeVariable ParseCalcVariable(const QHash<QString, OBSThemeVariable> &vars, const QString &value,
|
static OBSThemeVariable ParseMathVariable(const QHash<QString, OBSThemeVariable> &vars, const QString &value,
|
||||||
const int recursion = 0)
|
const int recursion = 0)
|
||||||
{
|
{
|
||||||
OBSThemeVariable var;
|
OBSThemeVariable var;
|
||||||
@ -527,15 +547,17 @@ static OBSThemeVariable ParseCalcVariable(const QHash<QString, OBSThemeVariable>
|
|||||||
var.value = value;
|
var.value = value;
|
||||||
ResolveVariable(vars, var);
|
ResolveVariable(vars, var);
|
||||||
|
|
||||||
/* Handle nested calc()s */
|
/* Handle nested math calculations */
|
||||||
if (var.type == OBSThemeVariable::Calc) {
|
if (var.type == OBSThemeVariable::Calc || var.type == OBSThemeVariable::Max ||
|
||||||
QString val = EvalCalc(vars, var, recursion + 1);
|
var.type == OBSThemeVariable::Min) {
|
||||||
var = ParseCalcVariable(vars, val);
|
QString val = EvalMath(vars, var, var.type, recursion + 1);
|
||||||
|
var = ParseMathVariable(vars, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only number or size would be valid here */
|
/* Only number or size would be valid here */
|
||||||
if (var.type != OBSThemeVariable::Number && var.type != OBSThemeVariable::Size) {
|
if (var.type != OBSThemeVariable::Number && var.type != OBSThemeVariable::Size) {
|
||||||
blog(LOG_ERROR, "calc() operand is not a size or number: %s", QT_TO_UTF8(var.value.toString()));
|
blog(LOG_ERROR, "Math operand is not a size or number: %s %s %d", QT_TO_UTF8(var.name),
|
||||||
|
QT_TO_UTF8(var.value.toString()), var.type);
|
||||||
throw invalid_argument("Operand not of numeric type");
|
throw invalid_argument("Operand not of numeric type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -543,54 +565,67 @@ static OBSThemeVariable ParseCalcVariable(const QHash<QString, OBSThemeVariable>
|
|||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString EvalCalc(const QHash<QString, OBSThemeVariable> &vars, const OBSThemeVariable &var, const int recursion)
|
static QString EvalMath(const QHash<QString, OBSThemeVariable> &vars, const OBSThemeVariable &var,
|
||||||
|
const OBSThemeVariable::VariableType type, const int recursion)
|
||||||
{
|
{
|
||||||
if (recursion >= 10) {
|
if (recursion >= 10) {
|
||||||
/* Abort after 10 levels of recursion */
|
/* Abort after 10 levels of recursion */
|
||||||
blog(LOG_ERROR, "Maximum calc() recursion levels hit!");
|
blog(LOG_ERROR, "Maximum recursion levels hit!");
|
||||||
|
return "'Invalid expression'";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != OBSThemeVariable::Calc && type != OBSThemeVariable::Max && type != OBSThemeVariable::Min) {
|
||||||
|
blog(LOG_ERROR, "Invalid type for math operation!");
|
||||||
return "'Invalid expression'";
|
return "'Invalid expression'";
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList args = var.value.toStringList();
|
QStringList args = var.value.toStringList();
|
||||||
if (args.length() != 3) {
|
QString &opt = args[1];
|
||||||
blog(LOG_ERROR, "calc() had invalid number of arguments: %lld (%s)", args.length(),
|
if (type == OBSThemeVariable::Calc && (opt != '*' && opt != '+' && opt != '-' && opt != '/')) {
|
||||||
QT_TO_UTF8(args.join(", ")));
|
blog(LOG_ERROR, "Unknown/invalid calc() operator: %s", QT_TO_UTF8(opt));
|
||||||
return "'Invalid expression'";
|
return "'Invalid expression'";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString &opt = args[1];
|
if ((type == OBSThemeVariable::Max || type == OBSThemeVariable::Min) && opt != ',') {
|
||||||
if (opt != '*' && opt != '+' && opt != '-' && opt != '/') {
|
blog(LOG_ERROR, "Invalid math separator: %s", QT_TO_UTF8(opt));
|
||||||
blog(LOG_ERROR, "Unknown/invalid calc() operator: %s", QT_TO_UTF8(opt));
|
return "'Invalid expression'";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length() != 3) {
|
||||||
|
blog(LOG_ERROR, "Math parse had invalid number of arguments: %lld (%s)", args.length(),
|
||||||
|
QT_TO_UTF8(args.join(", ")));
|
||||||
return "'Invalid expression'";
|
return "'Invalid expression'";
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSThemeVariable val1, val2;
|
OBSThemeVariable val1, val2;
|
||||||
try {
|
try {
|
||||||
val1 = ParseCalcVariable(vars, args[0], recursion);
|
val1 = ParseMathVariable(vars, args[0], 0);
|
||||||
val2 = ParseCalcVariable(vars, args[2], recursion);
|
val2 = ParseMathVariable(vars, args[2], 0);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return "'Invalid expression'";
|
return "'Invalid expression'";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure that suffixes match (if any) */
|
/* Ensure that suffixes match (if any) */
|
||||||
if (!val1.suffix.isEmpty() && !val2.suffix.isEmpty() && val1.suffix != val2.suffix) {
|
if (!val1.suffix.isEmpty() && !val2.suffix.isEmpty() && val1.suffix != val2.suffix) {
|
||||||
blog(LOG_ERROR, "calc() requires suffixes to match or only one to be present! %s != %s",
|
blog(LOG_ERROR, "Math operation requires suffixes to match or only one to be present! %s != %s",
|
||||||
QT_TO_UTF8(val1.suffix), QT_TO_UTF8(val2.suffix));
|
QT_TO_UTF8(val1.suffix), QT_TO_UTF8(val2.suffix));
|
||||||
return "'Invalid expression'";
|
return "'Invalid expression'";
|
||||||
}
|
}
|
||||||
|
|
||||||
double val = numeric_limits<double>::quiet_NaN();
|
|
||||||
double d1 = val1.userValue.isValid() ? val1.userValue.toDouble() : val1.value.toDouble();
|
double d1 = val1.userValue.isValid() ? val1.userValue.toDouble() : val1.value.toDouble();
|
||||||
double d2 = val2.userValue.isValid() ? val2.userValue.toDouble() : val2.value.toDouble();
|
double d2 = val2.userValue.isValid() ? val2.userValue.toDouble() : val2.value.toDouble();
|
||||||
|
|
||||||
if (!isfinite(d1) || !isfinite(d2)) {
|
if (!isfinite(d1) || !isfinite(d2)) {
|
||||||
blog(LOG_ERROR,
|
blog(LOG_ERROR,
|
||||||
"calc() received at least one invalid value:"
|
"At least one invalid math value:"
|
||||||
" op1: %f, op2: %f",
|
" op1: %f, op2: %f",
|
||||||
d1, d2);
|
d1, d2);
|
||||||
return "'Invalid expression'";
|
return "'Invalid expression'";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double val = numeric_limits<double>::quiet_NaN();
|
||||||
|
|
||||||
|
if (type == OBSThemeVariable::Calc) {
|
||||||
if (opt == "+")
|
if (opt == "+")
|
||||||
val = d1 + d2;
|
val = d1 + d2;
|
||||||
else if (opt == "-")
|
else if (opt == "-")
|
||||||
@ -601,12 +636,15 @@ static QString EvalCalc(const QHash<QString, OBSThemeVariable> &vars, const OBST
|
|||||||
val = d1 / d2;
|
val = d1 / d2;
|
||||||
|
|
||||||
if (!isnormal(val)) {
|
if (!isnormal(val)) {
|
||||||
blog(LOG_ERROR,
|
blog(LOG_ERROR, "Invalid calc() resulted in non-normal number: %f %s %f = %f", d1,
|
||||||
"Invalid calc() math resulted in non-normal number:"
|
QT_TO_UTF8(opt), d2, val);
|
||||||
" %f %s %f = %f",
|
|
||||||
d1, QT_TO_UTF8(opt), d2, val);
|
|
||||||
return "'Invalid expression'";
|
return "'Invalid expression'";
|
||||||
}
|
}
|
||||||
|
} else if (type == OBSThemeVariable::Max) {
|
||||||
|
val = d1 > d2 ? d1 : d2;
|
||||||
|
} else if (type == OBSThemeVariable::Min) {
|
||||||
|
val = d1 < d2 ? d1 : d2;
|
||||||
|
}
|
||||||
|
|
||||||
bool isInteger = ceill(val) == val;
|
bool isInteger = ceill(val) == val;
|
||||||
QString result = QString::number(val, 'f', isInteger ? 0 : -1);
|
QString result = QString::number(val, 'f', isInteger ? 0 : -1);
|
||||||
@ -661,8 +699,9 @@ static QString PrepareQSS(const QHash<QString, OBSThemeVariable> &vars, const QS
|
|||||||
|
|
||||||
if (var.type == OBSThemeVariable::Color) {
|
if (var.type == OBSThemeVariable::Color) {
|
||||||
replace = value.value<QColor>().name(QColor::HexRgb);
|
replace = value.value<QColor>().name(QColor::HexRgb);
|
||||||
} else if (var.type == OBSThemeVariable::Calc) {
|
} else if (var.type == OBSThemeVariable::Calc || var.type == OBSThemeVariable::Max ||
|
||||||
replace = EvalCalc(vars, var);
|
var.type == OBSThemeVariable::Min) {
|
||||||
|
replace = EvalMath(vars, var, var.type);
|
||||||
} else if (var.type == OBSThemeVariable::Size || var.type == OBSThemeVariable::Number) {
|
} else if (var.type == OBSThemeVariable::Size || var.type == OBSThemeVariable::Number) {
|
||||||
double val = value.toDouble();
|
double val = value.toDouble();
|
||||||
bool isInteger = ceill(val) == val;
|
bool isInteger = ceill(val) == val;
|
||||||
@ -747,6 +786,23 @@ static QPalette PreparePalette(const QHash<QString, OBSThemeVariable> &vars, con
|
|||||||
return pal;
|
return pal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double getPaddingForDensityId(int id)
|
||||||
|
{
|
||||||
|
double paddingValue = 4;
|
||||||
|
|
||||||
|
if (id == -2) {
|
||||||
|
paddingValue = 0.25;
|
||||||
|
} else if (id == -3) {
|
||||||
|
paddingValue = 2;
|
||||||
|
} else if (id == -4) {
|
||||||
|
paddingValue = 4;
|
||||||
|
} else if (id == -5) {
|
||||||
|
paddingValue = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
return paddingValue;
|
||||||
|
}
|
||||||
|
|
||||||
OBSTheme *OBSApp::GetTheme(const QString &name)
|
OBSTheme *OBSApp::GetTheme(const QString &name)
|
||||||
{
|
{
|
||||||
if (!themes.contains(name))
|
if (!themes.contains(name))
|
||||||
@ -775,6 +831,22 @@ bool OBSApp::SetTheme(const QString &name)
|
|||||||
QStringList themeIds(theme->dependencies);
|
QStringList themeIds(theme->dependencies);
|
||||||
themeIds << theme->id;
|
themeIds << theme->id;
|
||||||
|
|
||||||
|
/* Inject Appearance settings into theme vars */
|
||||||
|
OBSThemeVariable fontScale;
|
||||||
|
fontScale.name = "obsFontScale";
|
||||||
|
fontScale.type = OBSThemeVariable::Number;
|
||||||
|
fontScale.value = QVariant::fromValue(config_get_int(App()->GetUserConfig(), "Appearance", "FontScale"));
|
||||||
|
|
||||||
|
const int density = config_get_int(App()->GetUserConfig(), "Appearance", "Density");
|
||||||
|
|
||||||
|
OBSThemeVariable padding;
|
||||||
|
padding.name = "obsPadding";
|
||||||
|
padding.type = OBSThemeVariable::Number;
|
||||||
|
padding.value = QVariant::fromValue(getPaddingForDensityId(density));
|
||||||
|
|
||||||
|
vars[fontScale.name] = std::move(fontScale);
|
||||||
|
vars[padding.name] = std::move(padding);
|
||||||
|
|
||||||
/* Find and add high contrast adjustment layer if available */
|
/* Find and add high contrast adjustment layer if available */
|
||||||
if (HighContrastEnabled()) {
|
if (HighContrastEnabled()) {
|
||||||
for (const OBSTheme &theme_ : themes) {
|
for (const OBSTheme &theme_ : themes) {
|
||||||
@ -805,6 +877,22 @@ bool OBSApp::SetTheme(const QString &name)
|
|||||||
contents.emplaceBack(content.constData());
|
contents.emplaceBack(content.constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if OBS appearance settings are used in the theme */
|
||||||
|
currentTheme->usesFontScale = false;
|
||||||
|
currentTheme->usesDensity = false;
|
||||||
|
for (const OBSThemeVariable &var_ : vars) {
|
||||||
|
if (var_.type != OBSThemeVariable::Alias)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (var_.value.toString() == "obsFontScale") {
|
||||||
|
currentTheme->usesFontScale = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var_.value.toString() == "obsPadding") {
|
||||||
|
currentTheme->usesDensity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const QString stylesheet = PrepareQSS(vars, contents);
|
const QString stylesheet = PrepareQSS(vars, contents);
|
||||||
const QPalette palette = PreparePalette(vars, defaultPalette);
|
const QPalette palette = PreparePalette(vars, defaultPalette);
|
||||||
setPalette(palette);
|
setPalette(palette);
|
||||||
|
@ -1,16 +1,23 @@
|
|||||||
#include "AbsoluteSlider.hpp"
|
#include "AbsoluteSlider.hpp"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
#include "moc_AbsoluteSlider.cpp"
|
#include "moc_AbsoluteSlider.cpp"
|
||||||
|
|
||||||
AbsoluteSlider::AbsoluteSlider(QWidget *parent) : SliderIgnoreScroll(parent)
|
AbsoluteSlider::AbsoluteSlider(QWidget *parent) : SliderIgnoreScroll(parent)
|
||||||
{
|
{
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
|
tickColor.setRgb(0x5b, 0x62, 0x73);
|
||||||
}
|
}
|
||||||
|
|
||||||
AbsoluteSlider::AbsoluteSlider(Qt::Orientation orientation, QWidget *parent) : SliderIgnoreScroll(orientation, parent)
|
AbsoluteSlider::AbsoluteSlider(Qt::Orientation orientation, QWidget *parent) : SliderIgnoreScroll(orientation, parent)
|
||||||
{
|
{
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
|
tickColor.setRgb(0x5b, 0x62, 0x73);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbsoluteSlider::mousePressEvent(QMouseEvent *event)
|
void AbsoluteSlider::mousePressEvent(QMouseEvent *event)
|
||||||
@ -96,3 +103,64 @@ int AbsoluteSlider::posToRangeValue(QMouseEvent *event)
|
|||||||
|
|
||||||
return sliderValue;
|
return sliderValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AbsoluteSlider::getDisplayTicks() const
|
||||||
|
{
|
||||||
|
return displayTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbsoluteSlider::setDisplayTicks(bool display)
|
||||||
|
{
|
||||||
|
displayTicks = display;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor AbsoluteSlider::getTickColor() const
|
||||||
|
{
|
||||||
|
return tickColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbsoluteSlider::setTickColor(QColor c)
|
||||||
|
{
|
||||||
|
tickColor = std::move(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbsoluteSlider::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
if (!getDisplayTicks()) {
|
||||||
|
QSlider::paintEvent(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainter painter(this);
|
||||||
|
|
||||||
|
QStyleOptionSlider opt;
|
||||||
|
initStyleOption(&opt);
|
||||||
|
|
||||||
|
QRect groove = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this);
|
||||||
|
QRect handle = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
|
||||||
|
|
||||||
|
const bool isHorizontal = orientation() == Qt::Horizontal;
|
||||||
|
|
||||||
|
const int sliderLength = isHorizontal ? groove.width() - handle.width() : groove.height() - handle.height();
|
||||||
|
const int handleSize = isHorizontal ? handle.width() : handle.height();
|
||||||
|
const int grooveSize = isHorizontal ? groove.height() : groove.width();
|
||||||
|
const int grooveStart = isHorizontal ? groove.left() : groove.top();
|
||||||
|
const int tickLinePos = isHorizontal ? groove.center().y() : groove.center().x();
|
||||||
|
const int tickLength = std::max((int)(grooveSize * 1.5) + grooveSize, 8 + grooveSize);
|
||||||
|
const int tickLineStart = tickLinePos - (tickLength / 2) + 1;
|
||||||
|
|
||||||
|
for (double offset = minimum(); offset <= maximum(); offset += singleStep()) {
|
||||||
|
double tickPercent = (offset - minimum()) / (maximum() - minimum());
|
||||||
|
const int tickLineOffset = grooveStart + std::floor(sliderLength * tickPercent) + (handleSize / 2);
|
||||||
|
|
||||||
|
const int xPos = isHorizontal ? tickLineOffset : tickLineStart;
|
||||||
|
const int yPos = isHorizontal ? tickLineStart : tickLineOffset;
|
||||||
|
|
||||||
|
const int tickWidth = isHorizontal ? 1 : tickLength;
|
||||||
|
const int tickHeight = isHorizontal ? tickLength : 1;
|
||||||
|
|
||||||
|
painter.fillRect(xPos, yPos, tickWidth, tickHeight, tickColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSlider::paintEvent(event);
|
||||||
|
}
|
||||||
|
@ -4,11 +4,18 @@
|
|||||||
|
|
||||||
class AbsoluteSlider : public SliderIgnoreScroll {
|
class AbsoluteSlider : public SliderIgnoreScroll {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QColor tickColor READ getTickColor WRITE setTickColor DESIGNABLE true)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AbsoluteSlider(QWidget *parent = nullptr);
|
AbsoluteSlider(QWidget *parent = nullptr);
|
||||||
AbsoluteSlider(Qt::Orientation orientation, QWidget *parent = nullptr);
|
AbsoluteSlider(Qt::Orientation orientation, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
bool getDisplayTicks() const;
|
||||||
|
void setDisplayTicks(bool display);
|
||||||
|
|
||||||
|
QColor getTickColor() const;
|
||||||
|
void setTickColor(QColor c);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void absoluteSliderHovered(int value);
|
void absoluteSliderHovered(int value);
|
||||||
|
|
||||||
@ -20,6 +27,11 @@ protected:
|
|||||||
|
|
||||||
int posToRangeValue(QMouseEvent *event);
|
int posToRangeValue(QMouseEvent *event);
|
||||||
|
|
||||||
|
virtual void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool dragging = false;
|
bool dragging = false;
|
||||||
|
bool displayTicks = false;
|
||||||
|
|
||||||
|
QColor tickColor;
|
||||||
};
|
};
|
||||||
|
@ -93,15 +93,9 @@
|
|||||||
|
|
||||||
/* Layout */
|
/* Layout */
|
||||||
/* Configurable Values */
|
/* Configurable Values */
|
||||||
|
--font_base_value: var(--obsFontScale);
|
||||||
/* TODO: Min 8, Max 12, Step 1 */
|
--padding_base_value: var(--obsPadding);
|
||||||
--font_base_value: 10;
|
--spacing_base_value: calc(2 + calc(var(--obsPadding) / 2));
|
||||||
|
|
||||||
/* TODO: Min 2, Max 7, Step 1 */
|
|
||||||
--spacing_base_value: 4;
|
|
||||||
|
|
||||||
/* TODO: Min 0.25, Max 10, Step 2 */
|
|
||||||
--padding_base_value: 4;
|
|
||||||
|
|
||||||
/* TODO: Better Accessibility focus state */
|
/* TODO: Better Accessibility focus state */
|
||||||
/* TODO: Move Accessibilty Colors to Theme config system */
|
/* TODO: Move Accessibilty Colors to Theme config system */
|
||||||
@ -111,26 +105,27 @@
|
|||||||
--os_mac_font_base_value: 12;
|
--os_mac_font_base_value: 12;
|
||||||
|
|
||||||
--font_base: calc(1pt * var(--font_base_value));
|
--font_base: calc(1pt * var(--font_base_value));
|
||||||
--font_small: calc(0.9pt * var(--font_base_value));
|
--font_small: max(7pt, calc(0.8pt * var(--font_base_value)));
|
||||||
--font_xsmall: calc(0.85pt * var(--font_base_value));
|
--font_xsmall: max(6.25pt, calc(0.85pt * var(--font_base_value)));
|
||||||
--font_large: calc(1.1pt * var(--font_base_value));
|
--font_large: calc(1.1pt * var(--font_base_value));
|
||||||
--font_xlarge: calc(1.5pt * var(--font_base_value));
|
--font_xlarge: calc(1.5pt * var(--font_base_value));
|
||||||
|
|
||||||
--font_heading: calc(2.5pt * var(--font_base_value));
|
--font_heading: calc(2.5pt * var(--font_base_value));
|
||||||
|
|
||||||
--icon_base: calc(6px + var(--font_base_value));
|
--icon_base: calc(calc(max(2, var(--obsPadding)) * 1px) + 12px);
|
||||||
|
|
||||||
--spacing_base: calc(0.5px * var(--spacing_base_value));
|
--spacing_base: min(max(1px, calc(0.4 * var(--spacing_base_value))), 2px);
|
||||||
--spacing_large: calc(1px * var(--spacing_base_value));
|
--spacing_large: min(max(2px, calc(1px * var(--spacing_base_value))), 4px);
|
||||||
--spacing_small: calc(0.25px * var(--spacing_base_value));
|
--spacing_small: max(1px, calc(0.25px * var(--spacing_base_value)));
|
||||||
--spacing_title: 4px;
|
--spacing_title: 4px;
|
||||||
|
|
||||||
--padding_base: calc(0.5px * var(--padding_base_value));
|
--padding_base: calc(0.5px * var(--padding_base_value));
|
||||||
--padding_large: calc(1px * var(--padding_base_value));
|
--padding_large: min(max(1px, calc(1px * var(--padding_base_value))), 5px);
|
||||||
--padding_xlarge: calc(1.75px * var(--padding_base_value));
|
--padding_xlarge: min(max(2px, calc(1.75px * var(--padding_base_value))), 10px);
|
||||||
--padding_small: calc(0.25px * var(--padding_base_value));
|
--padding_small: max(0px, calc(0.25px * var(--padding_base_value)));
|
||||||
|
|
||||||
--padding_wide: calc(8px + calc(2 * var(--padding_base_value)));
|
--padding_container: max(4px, var(--padding_base));
|
||||||
|
--padding_wide: min(calc(12px + max(var(--padding_base_value), 4)), 24px);
|
||||||
--padding_menu: calc(4px + calc(2 * var(--padding_base_value)));
|
--padding_menu: calc(4px + calc(2 * var(--padding_base_value)));
|
||||||
|
|
||||||
--padding_base_border: calc(var(--padding_base) + 1px);
|
--padding_base_border: calc(var(--padding_base) + 1px);
|
||||||
@ -154,9 +149,10 @@
|
|||||||
--input_font_scale: calc(var(--font_base_value) * 2.2);
|
--input_font_scale: calc(var(--font_base_value) * 2.2);
|
||||||
--input_font_padding: calc(var(--padding_base_value) * 2);
|
--input_font_padding: calc(var(--padding_base_value) * 2);
|
||||||
|
|
||||||
--input_height_base: calc(var(--input_font_scale) + var(--input_font_padding));
|
--input_height_base: max(calc(var(--input_font_scale) + var(--input_font_padding)), 24);
|
||||||
--input_padding: var(--padding_large);
|
--input_padding: calc(2px + var(--padding_base));
|
||||||
--input_height: calc(var(--input_height_base) - calc(var(--input_padding) * 2));
|
--input_text_padding: max(calc(6px + var(--padding_base)), 8px);
|
||||||
|
--input_height: calc(var(--input_height_base) - calc(var(--input_padding) * 2px));
|
||||||
--input_height_half: calc(var(--input_height_base) / 2);
|
--input_height_half: calc(var(--input_height_base) / 2);
|
||||||
|
|
||||||
--input_bg: var(--grey4);
|
--input_bg: var(--grey4);
|
||||||
@ -196,6 +192,8 @@
|
|||||||
--scrollbar_down: var(--grey8);
|
--scrollbar_down: var(--grey8);
|
||||||
--scrollbar_border: var(--grey2);
|
--scrollbar_border: var(--grey2);
|
||||||
|
|
||||||
|
--preview_scale_width: calc(calc(var(--input_text_padding) * 3.5) * calc(var(--font_base_value) / 10));
|
||||||
|
|
||||||
--separator_hover: var(--white1);
|
--separator_hover: var(--white1);
|
||||||
|
|
||||||
--highlight: rgb(42, 130, 218);
|
--highlight: rgb(42, 130, 218);
|
||||||
@ -449,6 +447,9 @@ QListWidget QWidget {
|
|||||||
border: 1px solid var(--bg_base);
|
border: 1px solid var(--bg_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
spacing: var(--spacing_small);
|
||||||
|
}
|
||||||
|
|
||||||
/* Misc */
|
/* Misc */
|
||||||
|
|
||||||
@ -612,7 +613,7 @@ OBSDock > QWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#transitionsFrame {
|
#transitionsFrame {
|
||||||
padding: var(--padding_large);
|
padding: var(--padding_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSDock QLabel {
|
OBSDock QLabel {
|
||||||
@ -661,16 +662,15 @@ QScrollArea {
|
|||||||
* oversize it and use margin to crunch it back down
|
* oversize it and use margin to crunch it back down
|
||||||
*/
|
*/
|
||||||
OBSBasicStatusBar {
|
OBSBasicStatusBar {
|
||||||
margin-top: 4px;
|
margin-top: var(--spacing_large);
|
||||||
border-top: 1px solid var(--border_color);
|
border-top: 1px solid var(--border_color);
|
||||||
background: var(--bg_base);
|
background: var(--bg_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusBarWidget > QFrame {
|
StatusBarWidget > QFrame {
|
||||||
margin-top: 1px;
|
|
||||||
border: 0px solid var(--border_color);
|
border: 0px solid var(--border_color);
|
||||||
border-left-width: 1px;
|
border-left-width: 1px;
|
||||||
padding: 0px 8px 2px;
|
padding: 0px var(--padding_xlarge) var(--padding_small);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Group Box */
|
/* Group Box */
|
||||||
@ -803,6 +803,7 @@ QToolBar {
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
margin: var(--spacing_base) 0px;
|
margin: var(--spacing_base) 0px;
|
||||||
|
spacing: var(--spacing_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
QToolBarExtension {
|
QToolBarExtension {
|
||||||
@ -893,11 +894,10 @@ QTabBar QToolButton {
|
|||||||
QComboBox,
|
QComboBox,
|
||||||
QDateTimeEdit {
|
QDateTimeEdit {
|
||||||
background-color: var(--input_bg);
|
background-color: var(--input_bg);
|
||||||
border-style: solid;
|
|
||||||
border: 1px solid var(--input_bg);
|
border: 1px solid var(--input_bg);
|
||||||
border-radius: var(--border_radius);
|
border-radius: var(--border_radius);
|
||||||
padding: var(--padding_large) var(--padding_large);
|
padding: var(--input_padding) var(--input_text_padding);
|
||||||
padding-left: 10px;
|
height: var(--input_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
QComboBox QAbstractItemView {
|
QComboBox QAbstractItemView {
|
||||||
@ -974,8 +974,7 @@ QPlainTextEdit {
|
|||||||
background-color: var(--input_bg);
|
background-color: var(--input_bg);
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: var(--border_radius);
|
border-radius: var(--border_radius);
|
||||||
padding: var(--input_padding) var(--padding_small) var(--input_padding) var(--input_padding);
|
padding: var(--input_padding) var(--input_text_padding);
|
||||||
padding-left: 8px;
|
|
||||||
border: 1px solid var(--input_bg);
|
border: 1px solid var(--input_bg);
|
||||||
height: var(--input_height);
|
height: var(--input_height);
|
||||||
}
|
}
|
||||||
@ -994,6 +993,13 @@ QPlainTextEdit:focus {
|
|||||||
border-color: var(--input_border_focus);
|
border-color: var(--input_border_focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QLineEdit:read-only,
|
||||||
|
QLineEdit:read-only:hover,
|
||||||
|
QLineEdit:read-only:focus {
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: var(--input_bg);
|
||||||
|
}
|
||||||
|
|
||||||
QTextEdit:!editable,
|
QTextEdit:!editable,
|
||||||
QTextEdit:!editable:hover,
|
QTextEdit:!editable:hover,
|
||||||
QTextEdit:!editable:focus {
|
QTextEdit:!editable:focus {
|
||||||
@ -1007,8 +1013,8 @@ QDoubleSpinBox {
|
|||||||
background-color: var(--input_bg);
|
background-color: var(--input_bg);
|
||||||
border: 1px solid var(--input_bg);
|
border: 1px solid var(--input_bg);
|
||||||
border-radius: var(--border_radius);
|
border-radius: var(--border_radius);
|
||||||
padding: var(--input_padding) 0px var(--input_padding) var(--input_padding);
|
padding: var(--input_padding) var(--input_text_padding);
|
||||||
padding-left: 8px;
|
height: var(--input_height);
|
||||||
max-height: var(--input_height);
|
max-height: var(--input_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1096,7 +1102,7 @@ QDoubleSpinBox::down-arrow {
|
|||||||
|
|
||||||
/* Controls Dock */
|
/* Controls Dock */
|
||||||
#controlsFrame {
|
#controlsFrame {
|
||||||
padding: var(--padding_large);
|
padding: var(--padding_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
#controlsFrame QPushButton {
|
#controlsFrame QPushButton {
|
||||||
@ -1143,55 +1149,26 @@ QDoubleSpinBox::down-arrow {
|
|||||||
/* Buttons */
|
/* Buttons */
|
||||||
|
|
||||||
QPushButton {
|
QPushButton {
|
||||||
color: var(--text);
|
|
||||||
background-color: var(--button_bg);
|
background-color: var(--button_bg);
|
||||||
|
color: var(--text);
|
||||||
|
border: 1px solid var(--button_border);
|
||||||
border-radius: var(--border_radius);
|
border-radius: var(--border_radius);
|
||||||
height: var(--input_height);
|
height: var(--input_height);
|
||||||
max-height: var(--input_height);
|
max-height: var(--input_height);
|
||||||
|
margin-top: var(--spacing_input);
|
||||||
|
margin-bottom: var(--spacing_input);
|
||||||
padding: var(--input_padding) var(--padding_wide);
|
padding: var(--input_padding) var(--padding_wide);
|
||||||
icon-size: var(--icon_base);
|
icon-size: var(--icon_base);
|
||||||
}
|
outline: none;
|
||||||
|
|
||||||
QPushButton {
|
|
||||||
border: 1px solid var(--button_border);
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton {
|
|
||||||
border: 1px solid var(--button_border);
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton,
|
|
||||||
.btn-tool {
|
|
||||||
background-color: var(--button_bg);
|
|
||||||
padding: var(--padding_base) var(--padding_base);
|
|
||||||
margin: 0px var(--spacing_base);
|
|
||||||
border: 1px solid var(--button_border);
|
|
||||||
border-radius: var(--border_radius);
|
|
||||||
icon-size: var(--icon_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton:last-child,
|
|
||||||
.btn-tool:last-child {
|
|
||||||
margin-right: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton:hover,
|
|
||||||
QPushButton:focus {
|
|
||||||
border-color: var(--button_border_hover);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton:hover {
|
QPushButton:hover {
|
||||||
background-color: var(--button_bg_hover);
|
background-color: var(--button_bg_hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
QToolButton:hover,
|
QPushButton:hover,
|
||||||
QToolButton:focus,
|
QPushButton:focus {
|
||||||
.btn-tool:hover,
|
border-color: var(--button_border_hover);
|
||||||
.btn-tool:focus,
|
|
||||||
.indicator-mute::indicator:hover,
|
|
||||||
.indicator-mute::indicator:focus {
|
|
||||||
border-color: var(--button_border);
|
|
||||||
background-color: var(--button_bg_hover);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton::flat {
|
QPushButton::flat {
|
||||||
@ -1200,6 +1177,7 @@ QPushButton::flat {
|
|||||||
|
|
||||||
QPushButton:checked {
|
QPushButton:checked {
|
||||||
background-color: var(--primary);
|
background-color: var(--primary);
|
||||||
|
border-color: var(--primary_light);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton:checked:hover,
|
QPushButton:checked:hover,
|
||||||
@ -1213,6 +1191,47 @@ QPushButton:pressed:hover {
|
|||||||
border-color: var(--button_border);
|
border-color: var(--button_border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPushButton:disabled {
|
||||||
|
background-color: var(--button_bg_disabled);
|
||||||
|
border-color: var(--button_border);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton::menu-indicator {
|
||||||
|
image: url(theme:Dark/down.svg);
|
||||||
|
subcontrol-position: right;
|
||||||
|
subcontrol-origin: padding;
|
||||||
|
width: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton {
|
||||||
|
border: 1px solid var(--button_border);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton,
|
||||||
|
.btn-tool {
|
||||||
|
background-color: var(--button_bg);
|
||||||
|
padding: var(--padding_base) var(--padding_base);
|
||||||
|
margin: 0px 0px;
|
||||||
|
border: 1px solid var(--button_border);
|
||||||
|
border-radius: var(--border_radius);
|
||||||
|
icon-size: var(--icon_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:last-child,
|
||||||
|
.btn-tool:last-child {
|
||||||
|
margin-right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:hover,
|
||||||
|
QToolButton:focus,
|
||||||
|
.btn-tool:hover,
|
||||||
|
.btn-tool:focus,
|
||||||
|
.indicator-mute::indicator:hover,
|
||||||
|
.indicator-mute::indicator:focus {
|
||||||
|
border-color: var(--button_border);
|
||||||
|
background-color: var(--button_bg_hover);
|
||||||
|
}
|
||||||
|
|
||||||
QToolButton:pressed,
|
QToolButton:pressed,
|
||||||
QToolButton:pressed:hover,
|
QToolButton:pressed:hover,
|
||||||
.btn-tool:pressed,
|
.btn-tool:pressed,
|
||||||
@ -1221,24 +1240,12 @@ QToolButton:pressed:hover,
|
|||||||
border-color: var(--button_border);
|
border-color: var(--button_border);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton:disabled {
|
|
||||||
background-color: var(--button_bg_disabled);
|
|
||||||
border-color: var(--button_border);
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton:disabled,
|
QToolButton:disabled,
|
||||||
.btn-tool:disabled {
|
.btn-tool:disabled {
|
||||||
background-color: var(--button_bg_disabled);
|
background-color: var(--button_bg_disabled);
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton::menu-indicator {
|
|
||||||
image: url(theme:Dark/down.svg);
|
|
||||||
subcontrol-position: right;
|
|
||||||
subcontrol-origin: padding;
|
|
||||||
width: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sliders */
|
/* Sliders */
|
||||||
|
|
||||||
QSlider::groove {
|
QSlider::groove {
|
||||||
@ -1309,7 +1316,7 @@ QSlider::handle:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QSlider::handle:pressed {
|
QSlider::handle:pressed {
|
||||||
background-color: var(--white5);
|
background-color: var(--white3);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSlider::handle:disabled {
|
QSlider::handle:disabled {
|
||||||
@ -1349,6 +1356,15 @@ QSlider::handle:disabled {
|
|||||||
border-bottom: 1px solid #3c404b;
|
border-bottom: 1px solid #3c404b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VolControl {
|
||||||
|
background: var(--bg_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
VolControl QLabel {
|
||||||
|
font-size: var(--font_small);
|
||||||
|
margin: var(--spacing_small) 0px;
|
||||||
|
}
|
||||||
|
|
||||||
VolControl #volLabel {
|
VolControl #volLabel {
|
||||||
padding: var(--padding_base) 0px var(--padding_base);
|
padding: var(--padding_base) 0px var(--padding_base);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -1377,7 +1393,7 @@ VolControl #volLabel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#vMixerScrollArea VolControl {
|
#vMixerScrollArea VolControl {
|
||||||
padding: var(--padding_large) 0px var(--padding_base);
|
padding: var(--padding_container) 0px var(--padding_container);
|
||||||
border-right: 1px solid var(--border_color);
|
border-right: 1px solid var(--border_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1407,6 +1423,7 @@ VolControl #volLabel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#vMixerScrollArea VolControl QPushButton {
|
#vMixerScrollArea VolControl QPushButton {
|
||||||
|
margin-left: var(--spacing_base);
|
||||||
margin-right: var(--padding_xlarge);
|
margin-right: var(--padding_xlarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1414,10 +1431,6 @@ VolControl #volLabel {
|
|||||||
margin-left: var(--padding_xlarge);
|
margin-left: var(--padding_xlarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
VolControl {
|
|
||||||
background: var(--bg_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
VolumeMeter {
|
VolumeMeter {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
@ -1527,6 +1540,7 @@ QGroupBox::indicator,
|
|||||||
QTableView::indicator {
|
QTableView::indicator {
|
||||||
width: var(--icon_base);
|
width: var(--icon_base);
|
||||||
height: var(--icon_base);
|
height: var(--icon_base);
|
||||||
|
margin-right: var(--spacing_large);
|
||||||
}
|
}
|
||||||
|
|
||||||
QGroupBox::indicator {
|
QGroupBox::indicator {
|
||||||
@ -1952,7 +1966,7 @@ OBSBasicAdvAudio #scrollAreaWidgetContents {
|
|||||||
font-size: var(--font_xsmall);
|
font-size: var(--font_xsmall);
|
||||||
height: 14px;
|
height: 14px;
|
||||||
max-height: 14px;
|
max-height: 14px;
|
||||||
padding: 0px var(--padding_xlarge);
|
padding: 0px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
@ -1962,7 +1976,13 @@ OBSBasicAdvAudio #scrollAreaWidgetContents {
|
|||||||
border: 1px solid var(--grey6);
|
border: 1px solid var(--grey6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#previewScalePercent {
|
||||||
|
padding: 0px var(--input_text_padding);
|
||||||
|
min-width: var(--preview_scale_width);
|
||||||
|
}
|
||||||
|
|
||||||
#previewScalingMode {
|
#previewScalingMode {
|
||||||
|
padding: 0px var(--input_text_padding);
|
||||||
border: 1px solid var(--grey6);
|
border: 1px solid var(--grey6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,23 +24,13 @@
|
|||||||
--primary_light: rgb(33,71,109);
|
--primary_light: rgb(33,71,109);
|
||||||
|
|
||||||
/* Layout */
|
/* Layout */
|
||||||
--font_base_value: 9;
|
--font_small: max(7pt, calc(0.5pt * var(--font_base_value)));
|
||||||
--spacing_base_value: 2;
|
|
||||||
--padding_base_value: 0.25;
|
|
||||||
|
|
||||||
/* OS Fixes */
|
--padding_large: min(max(0px, calc(1px * var(--padding_base_value))), 5px);
|
||||||
--os_mac_font_base_value: 11;
|
|
||||||
|
|
||||||
--font_small: calc(0.75pt * var(--font_base_value));
|
--padding_container: max(2px, var(--padding_base));
|
||||||
|
|
||||||
--icon_base: calc(6px + var(--font_base_value));
|
/* Inputs / Controls */
|
||||||
|
|
||||||
--padding_xlarge: calc(2px + calc(0.5px * var(--padding_base_value)));
|
|
||||||
|
|
||||||
--padding_wide: calc(18px + calc(0.25 * var(--padding_base_value)));
|
|
||||||
--padding_menu: calc(8px + calc(1 * var(--padding_base_value)));
|
|
||||||
|
|
||||||
--input_height_base: calc(1px + calc(var(--input_font_scale) + var(--input_font_padding)));
|
|
||||||
|
|
||||||
--border_color: var(--grey6);
|
--border_color: var(--grey6);
|
||||||
|
|
||||||
@ -48,6 +38,10 @@
|
|||||||
--border_radius_small: 1px;
|
--border_radius_small: 1px;
|
||||||
--border_radius_large: 2px;
|
--border_radius_large: 2px;
|
||||||
|
|
||||||
|
--input_height_base: max(calc(var(--input_font_scale) + var(--input_font_padding)), 20);
|
||||||
|
--input_padding: calc(0px + var(--padding_base));
|
||||||
|
--input_text_padding: max(calc(6px + var(--padding_base)), 8px);
|
||||||
|
|
||||||
--input_bg: var(--grey4);
|
--input_bg: var(--grey4);
|
||||||
--input_bg_hover: var(--grey1);
|
--input_bg_hover: var(--grey1);
|
||||||
--input_bg_focus: var(--grey6);
|
--input_bg_focus: var(--grey6);
|
||||||
@ -263,7 +257,6 @@ QPushButton[toolButton="true"] {
|
|||||||
|
|
||||||
#vMixerScrollArea QLabel {
|
#vMixerScrollArea QLabel {
|
||||||
font-size: var(--font_small);
|
font-size: var(--font_small);
|
||||||
margin: var(--padding_xlarge) 0px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#vMixerScrollArea #volLabel {
|
#vMixerScrollArea #volLabel {
|
||||||
|
@ -979,7 +979,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="appearanceGeneral">
|
<widget class="QGroupBox" name="appearanceGeneral">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Basic.Settings.Appearance.General</string>
|
<string>Basic.Settings.Appearance</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
@ -1021,6 +1021,200 @@
|
|||||||
<widget class="QComboBox" name="themeVariant"/>
|
<widget class="QComboBox" name="themeVariant"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="appearanceSettingLabelFontScale">
|
||||||
|
<property name="text">
|
||||||
|
<string>Font Size</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>appearanceFontScale</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QFrame" name="frame_2">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_23" stretch="0,5">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="appearanceFontScaleText">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::NoFocus</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>10</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="clearButtonEnabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="AbsoluteSlider" name="appearanceFontScale">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>12</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksBothSides</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickInterval">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_20">
|
||||||
|
<property name="text">
|
||||||
|
<string>Density</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QFrame" name="frame_5">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_34">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="appearanceDensity1">
|
||||||
|
<property name="text">
|
||||||
|
<string>Classic</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoExclusive">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">appearanceDensityButtonGroup</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="appearanceDensity2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Compact</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoExclusive">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">appearanceDensityButtonGroup</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="appearanceDensity3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Normal</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoExclusive">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">appearanceDensityButtonGroup</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="appearanceDensity4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Comfortable</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoExclusive">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">appearanceDensityButtonGroup</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
<spacer name="horizontalSpacer_17">
|
<spacer name="horizontalSpacer_17">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
@ -1028,7 +1222,7 @@
|
|||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>170</width>
|
<width>170</width>
|
||||||
<height>0</height>
|
<height>10</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
@ -1049,6 +1243,31 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="appearanceOptionsWarning">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_35">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="appearanceOptionsWarningLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Some appearance options are not available for this style.</string>
|
||||||
|
</property>
|
||||||
|
<property name="class" stdset="0">
|
||||||
|
<string>text-warning</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -2898,8 +3117,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>766</width>
|
<width>424</width>
|
||||||
<height>592</height>
|
<height>175</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_14">
|
<layout class="QVBoxLayout" name="verticalLayout_14">
|
||||||
@ -3304,8 +3523,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>766</width>
|
<width>509</width>
|
||||||
<height>558</height>
|
<height>371</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -3945,8 +4164,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>766</width>
|
<width>625</width>
|
||||||
<height>558</height>
|
<height>489</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_27">
|
<layout class="QVBoxLayout" name="verticalLayout_27">
|
||||||
@ -4495,8 +4714,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>766</width>
|
<width>258</width>
|
||||||
<height>592</height>
|
<height>510</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_28">
|
<layout class="QVBoxLayout" name="verticalLayout_28">
|
||||||
@ -8479,6 +8698,11 @@
|
|||||||
<extends>QLineEdit</extends>
|
<extends>QLineEdit</extends>
|
||||||
<header>settings/OBSHotkeyEdit.hpp</header>
|
<header>settings/OBSHotkeyEdit.hpp</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>AbsoluteSlider</class>
|
||||||
|
<extends>QSlider</extends>
|
||||||
|
<header>components/AbsoluteSlider.hpp</header>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>listWidget</tabstop>
|
<tabstop>listWidget</tabstop>
|
||||||
@ -9058,4 +9282,7 @@
|
|||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
|
<buttongroups>
|
||||||
|
<buttongroup name="appearanceDensityButtonGroup"/>
|
||||||
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -297,6 +297,7 @@ void RestrictResetBitrates(initializer_list<QComboBox *> boxes, int maxbitrate);
|
|||||||
#define SCROLL_CHANGED &QSpinBox::valueChanged
|
#define SCROLL_CHANGED &QSpinBox::valueChanged
|
||||||
#define DSCROLL_CHANGED &QDoubleSpinBox::valueChanged
|
#define DSCROLL_CHANGED &QDoubleSpinBox::valueChanged
|
||||||
#define TEXT_CHANGED &QPlainTextEdit::textChanged
|
#define TEXT_CHANGED &QPlainTextEdit::textChanged
|
||||||
|
#define SLIDER_CHANGED &QSlider::valueChanged
|
||||||
|
|
||||||
#define GENERAL_CHANGED &OBSBasicSettings::GeneralChanged
|
#define GENERAL_CHANGED &OBSBasicSettings::GeneralChanged
|
||||||
#define STREAM1_CHANGED &OBSBasicSettings::Stream1Changed
|
#define STREAM1_CHANGED &OBSBasicSettings::Stream1Changed
|
||||||
@ -368,6 +369,11 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
|
|||||||
HookWidget(ui->multiviewLayout, COMBO_CHANGED, GENERAL_CHANGED);
|
HookWidget(ui->multiviewLayout, COMBO_CHANGED, GENERAL_CHANGED);
|
||||||
HookWidget(ui->theme, COMBO_CHANGED, APPEAR_CHANGED);
|
HookWidget(ui->theme, COMBO_CHANGED, APPEAR_CHANGED);
|
||||||
HookWidget(ui->themeVariant, COMBO_CHANGED, APPEAR_CHANGED);
|
HookWidget(ui->themeVariant, COMBO_CHANGED, APPEAR_CHANGED);
|
||||||
|
HookWidget(ui->appearanceFontScale, SLIDER_CHANGED, APPEAR_CHANGED);
|
||||||
|
HookWidget(ui->appearanceDensity1, CHECK_CHANGED, APPEAR_CHANGED);
|
||||||
|
HookWidget(ui->appearanceDensity2, CHECK_CHANGED, APPEAR_CHANGED);
|
||||||
|
HookWidget(ui->appearanceDensity3, CHECK_CHANGED, APPEAR_CHANGED);
|
||||||
|
HookWidget(ui->appearanceDensity4, CHECK_CHANGED, APPEAR_CHANGED);
|
||||||
HookWidget(ui->service, COMBO_CHANGED, STREAM1_CHANGED);
|
HookWidget(ui->service, COMBO_CHANGED, STREAM1_CHANGED);
|
||||||
HookWidget(ui->server, COMBO_CHANGED, STREAM1_CHANGED);
|
HookWidget(ui->server, COMBO_CHANGED, STREAM1_CHANGED);
|
||||||
HookWidget(ui->customServer, EDIT_CHANGED, STREAM1_CHANGED);
|
HookWidget(ui->customServer, EDIT_CHANGED, STREAM1_CHANGED);
|
||||||
|
@ -225,6 +225,8 @@ private:
|
|||||||
|
|
||||||
/* Appearance */
|
/* Appearance */
|
||||||
void InitAppearancePage();
|
void InitAppearancePage();
|
||||||
|
void enableAppearanceFontControls(bool enable);
|
||||||
|
void enableAppearanceDensityControls(bool enable);
|
||||||
|
|
||||||
bool IsCustomServer();
|
bool IsCustomServer();
|
||||||
|
|
||||||
@ -346,6 +348,7 @@ private:
|
|||||||
private slots:
|
private slots:
|
||||||
void on_theme_activated(int idx);
|
void on_theme_activated(int idx);
|
||||||
void on_themeVariant_activated(int idx);
|
void on_themeVariant_activated(int idx);
|
||||||
|
void updateAppearanceControls();
|
||||||
|
|
||||||
void on_listWidget_itemSelectionChanged();
|
void on_listWidget_itemSelectionChanged();
|
||||||
void on_buttonBox_clicked(QAbstractButton *button);
|
void on_buttonBox_clicked(QAbstractButton *button);
|
||||||
|
@ -21,6 +21,15 @@ void OBSBasicSettings::InitAppearancePage()
|
|||||||
ui->theme->setCurrentIndex(idx);
|
ui->theme->setCurrentIndex(idx);
|
||||||
|
|
||||||
ui->themeVariant->setPlaceholderText(QTStr("Basic.Settings.Appearance.General.NoVariant"));
|
ui->themeVariant->setPlaceholderText(QTStr("Basic.Settings.Appearance.General.NoVariant"));
|
||||||
|
|
||||||
|
ui->appearanceFontScale->setDisplayTicks(true);
|
||||||
|
|
||||||
|
connect(ui->appearanceFontScale, &QSlider::valueChanged, ui->appearanceFontScaleText,
|
||||||
|
[this](int value) { ui->appearanceFontScaleText->setText(QString::number(value)); });
|
||||||
|
ui->appearanceFontScaleText->setText(QString::number(ui->appearanceFontScale->value()));
|
||||||
|
|
||||||
|
connect(App(), &OBSApp::StyleChanged, this, &OBSBasicSettings::updateAppearanceControls);
|
||||||
|
updateAppearanceControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OBSBasicSettings::LoadThemeList(bool reload)
|
void OBSBasicSettings::LoadThemeList(bool reload)
|
||||||
@ -83,6 +92,16 @@ void OBSBasicSettings::LoadAppearanceSettings(bool reload)
|
|||||||
|
|
||||||
App()->SetTheme(themeId);
|
App()->SetTheme(themeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fontScale = config_get_int(App()->GetUserConfig(), "Appearance", "FontScale");
|
||||||
|
ui->appearanceFontScale->setValue(fontScale);
|
||||||
|
|
||||||
|
int densityId = config_get_int(App()->GetUserConfig(), "Appearance", "Density");
|
||||||
|
QAbstractButton *densityButton = ui->appearanceDensityButtonGroup->button(densityId);
|
||||||
|
if (densityButton) {
|
||||||
|
densityButton->setChecked(true);
|
||||||
|
}
|
||||||
|
updateAppearanceControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OBSBasicSettings::SaveAppearanceSettings()
|
void OBSBasicSettings::SaveAppearanceSettings()
|
||||||
@ -93,6 +112,13 @@ void OBSBasicSettings::SaveAppearanceSettings()
|
|||||||
if (savedTheme != currentTheme) {
|
if (savedTheme != currentTheme) {
|
||||||
config_set_string(config, "Appearance", "Theme", QT_TO_UTF8(currentTheme->id));
|
config_set_string(config, "Appearance", "Theme", QT_TO_UTF8(currentTheme->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config_set_int(config, "Appearance", "FontScale", ui->appearanceFontScale->value());
|
||||||
|
|
||||||
|
int densityId = ui->appearanceDensityButtonGroup->checkedId();
|
||||||
|
config_set_int(config, "Appearance", "Density", densityId);
|
||||||
|
|
||||||
|
App()->SetTheme(currentTheme->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OBSBasicSettings::on_theme_activated(int)
|
void OBSBasicSettings::on_theme_activated(int)
|
||||||
@ -104,3 +130,30 @@ void OBSBasicSettings::on_themeVariant_activated(int)
|
|||||||
{
|
{
|
||||||
LoadAppearanceSettings(true);
|
LoadAppearanceSettings(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OBSBasicSettings::updateAppearanceControls()
|
||||||
|
{
|
||||||
|
OBSTheme *theme = App()->GetTheme();
|
||||||
|
enableAppearanceFontControls(theme->usesFontScale);
|
||||||
|
enableAppearanceDensityControls(theme->usesDensity);
|
||||||
|
if (!theme->usesFontScale || !theme->usesDensity) {
|
||||||
|
ui->appearanceOptionsWarning->setVisible(true);
|
||||||
|
} else {
|
||||||
|
ui->appearanceOptionsWarning->setVisible(false);
|
||||||
|
}
|
||||||
|
style()->polish(ui->appearanceOptionsWarningLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OBSBasicSettings::enableAppearanceFontControls(bool enable)
|
||||||
|
{
|
||||||
|
ui->appearanceFontScale->setEnabled(enable);
|
||||||
|
ui->appearanceFontScaleText->setEnabled(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OBSBasicSettings::enableAppearanceDensityControls(bool enable)
|
||||||
|
{
|
||||||
|
const QList<QAbstractButton *> buttons = ui->appearanceDensityButtonGroup->buttons();
|
||||||
|
for (QAbstractButton *button : buttons) {
|
||||||
|
button->setEnabled(enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -41,4 +41,7 @@ struct OBSTheme {
|
|||||||
bool isVisible; /* Whether it should be shown to the user */
|
bool isVisible; /* Whether it should be shown to the user */
|
||||||
bool isBaseTheme; /* Whether it is a "style" or variant */
|
bool isBaseTheme; /* Whether it is a "style" or variant */
|
||||||
bool isHighContrast; /* Whether it is a high-contrast adjustment layer */
|
bool isHighContrast; /* Whether it is a high-contrast adjustment layer */
|
||||||
|
|
||||||
|
bool usesFontScale = false; /* Whether the generated QSS uses the font scale option */
|
||||||
|
bool usesDensity = false; /* Whether the generated QSS uses the density option */
|
||||||
};
|
};
|
||||||
|
@ -28,6 +28,8 @@ struct OBSThemeVariable {
|
|||||||
String, /* Raw string (e.g. color name, border style, etc.) */
|
String, /* Raw string (e.g. color name, border style, etc.) */
|
||||||
Alias, /* Points at another variable, value will be the key */
|
Alias, /* Points at another variable, value will be the key */
|
||||||
Calc, /* Simple calculation with two operands */
|
Calc, /* Simple calculation with two operands */
|
||||||
|
Min, /* Get the smallest of two Size or Number */
|
||||||
|
Max, /* Get the largest of two Size or Number */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Whether the variable should be editable in the UI */
|
/* Whether the variable should be editable in the UI */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user