diff --git a/UI/data/themes/Acri.qss b/UI/data/themes/Acri.qss
index 25d4f297d14cb2e661e38f77894d674b695365c4..9f3dd3087c11e997a60686b3e6a94b88a4f99b52 100644
--- a/UI/data/themes/Acri.qss
+++ b/UI/data/themes/Acri.qss
@@ -985,3 +985,11 @@ VisibilityCheckBox::indicator:checked:hover {
VisibilityCheckBox::indicator:unchecked:hover {
image: url(:res/images/invisible.svg);
}
+
+* [themeID="trashIcon"] {
+ qproperty-icon: url(./Dark/trash.svg);
+}
+
+* [themeID="revertIcon"] {
+ qproperty-icon: url(./Dark/revert.svg);
+}
diff --git a/UI/data/themes/Dark.qss b/UI/data/themes/Dark.qss
index 08f4ea1e4322be38b171b44a57276845c8fcc03a..890f084dd519cbf44fbbd0ee99240a0c8b364c5b 100644
--- a/UI/data/themes/Dark.qss
+++ b/UI/data/themes/Dark.qss
@@ -119,12 +119,7 @@ QListWidget QLineEdit {
QDockWidget::title {
text-align: center;
- 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));
+ background-color: rgb(70,69,70);
}
QDockWidget::close-button, QDockWidget::float-button {
@@ -158,21 +153,18 @@ QGroupBox {
}
QScrollBar:vertical {
- background-color: rgb(58,57,58); /* dark */
+ background-color: rgb(58,57,58);
width: 14px;
margin: 0px;
}
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 */
+ background-color: rgb(76,76,76);
min-height: 20px;
margin: 2px;
border-radius: 5px;
border-width: 1px;
- border: 1px solid rgb(31,30,31); /* veryDark */
+ border: 1px solid rgb(76,76,76);
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
@@ -194,15 +186,12 @@ QScrollBar:horizontal {
}
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 */
+ background-color: rgb(76,76,76);
min-width: 20px;
margin: 2px;
border-radius: 5px;
border-width: 1px;
- border: 1px solid rgb(31,30,31); /* veryDark */
+ border: 1px solid rgb(76,76,76);
}
QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal {
@@ -271,11 +260,11 @@ QTabWidget::pane { /* The tab widget frame */
}
QTabWidget::tab-bar {
- alignment: center;
+ alignment: left;
}
QTabBar::tab {
- background-color: rgb(88,87,88); /* kindaDark */
+ background-color: rgb(76,76,76);
border: none;
padding: 5px;
min-width: 50px;
@@ -284,16 +273,16 @@ QTabBar::tab {
QTabBar::tab:top {
border-bottom: 1px transparent;
- border-top-left-radius: 5px;
- border-top-right-radius: 5px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
}
QTabBar::tab:bottom {
padding-top: 1px;
margin-bottom: 4px;
- border-bottom-left-radius: 5px;
- border-bottom-right-radius: 5px;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
height: 14px;
}
@@ -313,25 +302,17 @@ QTabBar::tab:pressed {
/* 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));
+ background-color: rgb(76,76,76);
border-style: solid;
border: 1px;
border-radius: 3px;
- border-color: rgb(31,30,31); /* veryDark */
+ border-color: rgb(76,76,76); /* veryDark */
padding: 2px;
padding-left: 10px;
}
QComboBox:hover {
- background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
- stop: 0 rgb(111, 110, 101),
- stop: 0.25 rgb(100, 99, 100),
- stop: 1 rgb(88,87,88));
+ background-color: rgb(88,87,88);
}
QComboBox::drop-down {
@@ -395,7 +376,7 @@ 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 */
+ background-color: rgb(76,76,76);
border: 1px solid rgb(31,30,31); /* veryDark */
border-radius: 3px;
border-width: 0;
@@ -407,7 +388,7 @@ QSpinBox::up-button, QDoubleSpinBox::up-button {
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 */
+ background-color: rgb(76,76,76);
border: 1px solid rgb(31,30,31); /* veryDark */
border-radius: 3px;
border-width: 0;
@@ -447,7 +428,7 @@ QSpinBox::down-arrow, QDoubleSpinBox::down-arrow {
QPushButton {
color: rgb(225,224,225); /* veryLight */
- background-color: rgb(88,87,88); /* kindaDark */
+ background-color: rgb(76,76,76);
border: none;
border-radius: 3px;
padding: 4px;
@@ -485,20 +466,15 @@ QPushButton[themeID="hotkeyButtons"] {
/* Sliders */
QSlider::groove:horizontal {
- background-color: QLinearGradient(x1: 0, y1: 1, x2: 0, y2: 0,
- stop: 0 rgb(50, 49, 50), /* dark */
- stop: 0.75 rgb(88,87,88)); /* kindaDark */
+ background-color: rgb(76,76,76);
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 */
+ background-color: #d2d2d2;
+ border: 1px solid rgb(58,57,58);
border-radius: 3px;
height: 10px;
width: 18px;
@@ -506,10 +482,7 @@ QSlider::handle:horizontal {
}
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 */
+ background-color: #d2d2d2;
}
QSlider::sub-page:horizontal {
@@ -518,27 +491,20 @@ QSlider::sub-page:horizontal {
}
QSlider::sub-page:horizontal:disabled {
- background-color: QLinearGradient(x1: 0, y1: 1, x2: 0, y2: 0,
- stop: 0 rgb(31,30,31), /* veryDark */
- stop: 0.75 rgb(50, 49, 50)); /* dark */
+ background-color: rgb(50, 49, 50); /* dark */
border-radius: 2px;
}
QSlider::groove:vertical {
- background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0,
- stop: 0 rgb(50, 49, 50), /* dark */
- stop: 0.75 rgb(88,87,88)); /* kindaDark */
+ background-color: rgb(76,76,76);
width: 4px;
border: none;
border-radius: 2px;
}
QSlider::handle:vertical {
- 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 */
- border: 1px solid rgb(58,57,58); /* dark */
+ background-color: #d2d2d2;
+ border: 1px solid rgb(58,57,58);
border-radius: 3px;
width: 10px;
height: 18px;
@@ -546,10 +512,7 @@ QSlider::handle:vertical {
}
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 */
+ background-color: #d2d2d2;
}
QSlider::add-page:vertical {
@@ -558,9 +521,7 @@ QSlider::add-page:vertical {
}
QSlider::add-page:vertical:disabled {
- background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0,
- stop: 0 rgb(31,30,31), /* veryDark */
- stop: 0.75 rgb(50, 49, 50)); /* dark */
+ background-color: rgb(50, 49, 50); /* dark */
border-radius: 2px;
}
@@ -747,3 +708,11 @@ VisibilityCheckBox::indicator:checked {
VisibilityCheckBox::indicator:unchecked {
image: url(:res/images/invisible.svg);
}
+
+* [themeID="trashIcon"] {
+ qproperty-icon: url(./Dark/trash.svg);
+}
+
+* [themeID="revertIcon"] {
+ qproperty-icon: url(./Dark/revert.svg);
+}
diff --git a/UI/data/themes/Dark/revert.svg b/UI/data/themes/Dark/revert.svg
new file mode 100644
index 0000000000000000000000000000000000000000..38d01706b554e352ae39fd16a4f48e23b078d113
--- /dev/null
+++ b/UI/data/themes/Dark/revert.svg
@@ -0,0 +1 @@
+
diff --git a/UI/data/themes/Dark/trash.svg b/UI/data/themes/Dark/trash.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2748485b33cd150612ac94e76d7f57157b6bf0ca
--- /dev/null
+++ b/UI/data/themes/Dark/trash.svg
@@ -0,0 +1 @@
+
diff --git a/UI/data/themes/Rachni.qss b/UI/data/themes/Rachni.qss
index 3794d2599ee162fb49be46ede4e2bdc1a40d7a6a..28cdbb0c3776e932dc451fbf730cc4aaa2068f37 100644
--- a/UI/data/themes/Rachni.qss
+++ b/UI/data/themes/Rachni.qss
@@ -1339,3 +1339,11 @@ VisibilityCheckBox::indicator:checked:hover {
VisibilityCheckBox::indicator:unchecked:hover {
image: url(:res/images/invisible.svg);
}
+
+* [themeID="trashIcon"] {
+ qproperty-icon: url(./Dark/trash.svg);
+}
+
+* [themeID="revertIcon"] {
+ qproperty-icon: url(./Dark/revert.svg);
+}
diff --git a/UI/data/themes/System.qss b/UI/data/themes/System.qss
index d9eff8c3436e8453a6f88c1242223c996d4fcd6f..16d0f47e19bb36a1f15d70fca4d40d74185ee0a2 100644
--- a/UI/data/themes/System.qss
+++ b/UI/data/themes/System.qss
@@ -191,3 +191,11 @@ VisibilityCheckBox::indicator:checked {
VisibilityCheckBox::indicator:unchecked {
image: url(:res/images/invisible.svg);
}
+
+* [themeID="trashIcon"] {
+ qproperty-icon: url(:res/images/trash.svg);
+}
+
+* [themeID="revertIcon"] {
+ qproperty-icon: url(:res/images/revert.svg);
+}
diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui
index d977af980567d5a09177b647cc619095dc01f9ac..328a8874461fe9da69ebb4bc513676cc33966028 100644
--- a/UI/forms/OBSBasicSettings.ui
+++ b/UI/forms/OBSBasicSettings.ui
@@ -1250,13 +1250,6 @@
- -
-
-
- Qt::Horizontal
-
-
-
-
@@ -2030,13 +2023,6 @@
- -
-
-
- Qt::Horizontal
-
-
-
-
@@ -3497,13 +3483,6 @@
- -
-
-
- Qt::Horizontal
-
-
-
-
diff --git a/UI/forms/images/revert.svg b/UI/forms/images/revert.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d1e13143cea94c62ddb55ceb63cf20070acccf99
--- /dev/null
+++ b/UI/forms/images/revert.svg
@@ -0,0 +1 @@
+
diff --git a/UI/forms/images/trash.svg b/UI/forms/images/trash.svg
new file mode 100644
index 0000000000000000000000000000000000000000..fdc9bc266827ff133ca83d5436f93b5ec40feab7
--- /dev/null
+++ b/UI/forms/images/trash.svg
@@ -0,0 +1 @@
+
diff --git a/UI/forms/obs.qrc b/UI/forms/obs.qrc
index fb5fb6557e8182e92e2aee0cd9ccc4a23569ef01..7c647c7b7c615b1aabbbba6e38b5ee1b1c1ffd62 100644
--- a/UI/forms/obs.qrc
+++ b/UI/forms/obs.qrc
@@ -14,6 +14,8 @@
images/locked.svg
images/invisible.svg
images/visible.svg
+ images/trash.svg
+ images/revert.svg
images/settings/output.svg
diff --git a/UI/hotkey-edit.cpp b/UI/hotkey-edit.cpp
index e76dc370d8f0d7c2dcfc5f0d81a3d2d97a066068..e0b05e19fb11be1d7ef60e209120ea0813d21c3f 100644
--- a/UI/hotkey-edit.cpp
+++ b/UI/hotkey-edit.cpp
@@ -272,13 +272,17 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
edit->setToolTip(toolTip);
auto revert = new QPushButton;
- revert->setProperty("themeID", "hotkeyButtons");
- revert->setText(QTStr("Revert"));
+ revert->setProperty("themeID", "revertIcon");
+ revert->setToolTip(QTStr("Revert"));
+ revert->setFixedSize(24, 24);
+ revert->setStyleSheet("background: transparent; border: none;");
revert->setEnabled(false);
auto clear = new QPushButton;
- clear->setProperty("themeID", "hotkeyButtons");
- clear->setText(QTStr("Clear"));
+ clear->setProperty("themeID", "trashIcon");
+ clear->setToolTip(QTStr("Clear"));
+ clear->setFixedSize(24, 24);
+ clear->setStyleSheet("background: transparent; border: none;");
clear->setEnabled(!obs_key_combination_is_empty(combo));
QObject::connect(edit, &OBSHotkeyEdit::KeyChanged,
@@ -289,15 +293,15 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
});
auto add = new QPushButton;
- add->setProperty("themeID", "hotkeyButtons");
- add->setText("+");
- add->setMinimumWidth(50);
+ add->setProperty("themeID", "addIconSmall");
+ add->setFixedSize(24, 24);
+ add->setStyleSheet("background: transparent; border: none;");
auto remove = new QPushButton;
- remove->setProperty("themeID", "hotkeyButtons");
- remove->setText("-");
+ remove->setProperty("themeID", "removeIconSmall");
remove->setEnabled(removeButtons.size() > 0);
- remove->setMinimumWidth(50);
+ remove->setFixedSize(24, 24);
+ remove->setStyleSheet("background: transparent; border: none;");
auto CurrentIndex = [&, remove]
{
diff --git a/UI/properties-view.cpp b/UI/properties-view.cpp
index b83670ef1e4e2a60c3455a926f4c25ace214d2f7..4f5fae19b97252b72429b7374b6a6ca695ba3ba9 100644
--- a/UI/properties-view.cpp
+++ b/UI/properties-view.cpp
@@ -333,12 +333,14 @@ void OBSPropertiesView::AddInt(obs_property_t *prop, QFormLayout *layout,
int minVal = obs_property_int_min(prop);
int maxVal = obs_property_int_max(prop);
int stepVal = obs_property_int_step(prop);
+ const char *suffix = obs_property_int_suffix(prop);
spin->setMinimum(minVal);
spin->setMaximum(maxVal);
spin->setSingleStep(stepVal);
spin->setValue(val);
spin->setToolTip(QT_UTF8(obs_property_long_description(prop)));
+ spin->setSuffix(QT_UTF8(suffix));
WidgetInfo *info = new WidgetInfo(this, prop, spin);
children.emplace_back(info);
@@ -382,12 +384,14 @@ void OBSPropertiesView::AddFloat(obs_property_t *prop, QFormLayout *layout,
double minVal = obs_property_float_min(prop);
double maxVal = obs_property_float_max(prop);
double stepVal = obs_property_float_step(prop);
+ const char *suffix = obs_property_float_suffix(prop);
spin->setMinimum(minVal);
spin->setMaximum(maxVal);
spin->setSingleStep(stepVal);
spin->setValue(val);
spin->setToolTip(QT_UTF8(obs_property_long_description(prop)));
+ spin->setSuffix(QT_UTF8(suffix));
WidgetInfo *info = new WidgetInfo(this, prop, spin);
children.emplace_back(info);
diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp
index 12ff7731b9cf46091c671fa3bd9407ba478305b9..00389307de9b08bc7f8a44e367a8d14765c17efc 100644
--- a/UI/window-basic-settings.cpp
+++ b/UI/window-basic-settings.cpp
@@ -463,7 +463,10 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
HookWidget(ui->autoRemux, CHECK_CHANGED, ADV_CHANGED);
ui->simpleOutputVBitrate->setSingleStep(50);
+ ui->simpleOutputVBitrate->setSuffix(" Kbps");
ui->advOutFFVBitrate->setSingleStep(50);
+ ui->advOutFFVBitrate->setSuffix(" Kbps");
+ ui->advOutFFABitrate->setSuffix(" Kbps");
#if !defined(_WIN32) && !defined(__APPLE__)
delete ui->enableAutoUpdates;
@@ -725,6 +728,10 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
this, SLOT(AdvOutRecCheckWarnings()));
AdvOutRecCheckWarnings();
+ ui->buttonBox->button(QDialogButtonBox::Apply)->setIcon(QIcon());
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setIcon(QIcon());
+ ui->buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QIcon());
+
SimpleRecordingQualityChanged();
UpdateAutomaticReplayBufferCheckboxes();
@@ -2322,12 +2329,22 @@ void OBSBasicSettings::LoadAdvancedSettings()
loading = false;
}
+#define TRUNCATE_TEXT_LENGTH 80
+
template
static inline void LayoutHotkey(obs_hotkey_id id, obs_hotkey_t *key, Func &&fun,
const map> &keys)
{
auto *label = new OBSHotkeyLabel;
- label->setText(obs_hotkey_get_description(key));
+ QString text = QT_UTF8(obs_hotkey_get_description(key));
+
+ if (text.length() > TRUNCATE_TEXT_LENGTH) {
+ label->setProperty("fullName", text);
+ text = text.left(TRUNCATE_TEXT_LENGTH);
+ text += "...'";
+ }
+
+ label->setText(text);
OBSHotkeyWidget *hw = nullptr;
@@ -2353,7 +2370,19 @@ static QLabel *makeLabel(T &t, Func &&getName)
template
static QLabel *makeLabel(const OBSSource &source, Func &&)
{
- return new OBSSourceLabel(source);
+ OBSSourceLabel *label = new OBSSourceLabel(source);
+ label->setStyleSheet("font-weight: bold;");
+ QString name = QT_UTF8(obs_source_get_name(source));
+
+ if (name.length() > TRUNCATE_TEXT_LENGTH) {
+ label->setToolTip(name);
+ name = name.left(TRUNCATE_TEXT_LENGTH);
+ name += "...";
+ }
+
+ label->setText(name);
+
+ return label;
}
template
@@ -2365,13 +2394,8 @@ static inline void AddHotkeys(QFormLayout &layout,
if (hotkeys.empty())
return;
- auto line = new QFrame();
- line->setFrameShape(QFrame::HLine);
- line->setFrameShadow(QFrame::Sunken);
-
layout.setItem(layout.rowCount(), QFormLayout::SpanningRole,
new QSpacerItem(0, 10));
- layout.addRow(line);
using tuple_type =
std::tuple, QPointer>;
@@ -2632,7 +2656,12 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey)
auto Update = [&](OBSHotkeyLabel *label, const QString &name,
OBSHotkeyLabel *other, const QString &otherName)
{
- label->setToolTip(tt.arg(otherName));
+ QString string = other->property("fullName").value();
+
+ if (string.isEmpty() || string.isNull())
+ string = otherName;
+
+ label->setToolTip(tt.arg(string));
label->setText(name + " *");
label->pairPartner = other;
};
@@ -4323,7 +4352,6 @@ void OBSBasicSettings::AdvReplayBufferChanged()
ui->advRBEstimate->setText(QTStr(ESTIMATE_UNKNOWN_STR));
ui->advReplayBufferGroupBox->setVisible(!lossless && replayBufferEnabled);
- ui->line_4->setVisible(!lossless && replayBufferEnabled);
ui->advReplayBuf->setEnabled(!lossless);
UpdateAutomaticReplayBufferCheckboxes();
diff --git a/libobs/obs-properties.c b/libobs/obs-properties.c
index ad62d5b4a412b1f079ee806fd6b730434f2dc7ea..2810e950ee110b32a3b9a28112202d922bebe2c7 100644
--- a/libobs/obs-properties.c
+++ b/libobs/obs-properties.c
@@ -27,11 +27,13 @@ static inline void *get_property_data(struct obs_property *prop);
struct float_data {
double min, max, step;
enum obs_number_type type;
+ char *suffix;
};
struct int_data {
int min, max, step;
enum obs_number_type type;
+ char *suffix;
};
struct list_item {
@@ -149,6 +151,16 @@ static inline void group_data_free(struct group_data *data) {
obs_properties_destroy(data->content);
}
+static inline void int_data_free(struct int_data *data) {
+ if (data->suffix)
+ bfree(data->suffix);
+}
+
+static inline void float_data_free(struct int_data *data) {
+ if (data->suffix)
+ bfree(data->suffix);
+}
+
struct obs_properties;
struct obs_property {
@@ -235,6 +247,10 @@ static void obs_property_destroy(struct obs_property *property)
frame_rate_data_free(get_property_data(property));
else if (property->type == OBS_PROPERTY_GROUP)
group_data_free(get_property_data(property));
+ else if (property->type == OBS_PROPERTY_INT)
+ int_data_free(get_property_data(property));
+ else if (property->type == OBS_PROPERTY_FLOAT)
+ float_data_free(get_property_data(property));
bfree(property->name);
bfree(property->desc);
@@ -855,6 +871,12 @@ enum obs_number_type obs_property_int_type(obs_property_t *p)
return data ? data->type : OBS_NUMBER_SCROLLER;
}
+const char *obs_property_int_suffix(obs_property_t *p)
+{
+ struct int_data *data = get_type_data(p, OBS_PROPERTY_INT);
+ return data ? data->suffix : NULL;
+}
+
double obs_property_float_min(obs_property_t *p)
{
struct float_data *data = get_type_data(p, OBS_PROPERTY_FLOAT);
@@ -873,6 +895,12 @@ double obs_property_float_step(obs_property_t *p)
return data ? data->step : 0;
}
+const char *obs_property_float_suffix(obs_property_t *p)
+{
+ struct int_data *data = get_type_data(p, OBS_PROPERTY_FLOAT);
+ return data ? data->suffix : NULL;
+}
+
enum obs_number_type obs_property_float_type(obs_property_t *p)
{
struct float_data *data = get_type_data(p, OBS_PROPERTY_FLOAT);
@@ -939,6 +967,26 @@ void obs_property_float_set_limits(obs_property_t *p,
data->step = step;
}
+void obs_property_int_set_suffix(obs_property_t *p, const char *suffix)
+{
+ struct int_data *data = get_type_data(p, OBS_PROPERTY_INT);
+ if (!data)
+ return;
+
+ bfree(data->suffix);
+ data->suffix = bstrdup(suffix);
+}
+
+void obs_property_float_set_suffix(obs_property_t *p, const char *suffix)
+{
+ struct float_data *data = get_type_data(p, OBS_PROPERTY_FLOAT);
+ if (!data)
+ return;
+
+ bfree(data->suffix);
+ data->suffix = bstrdup(suffix);
+}
+
void obs_property_list_clear(obs_property_t *p)
{
struct list_data *data = get_list_data(p);
diff --git a/libobs/obs-properties.h b/libobs/obs-properties.h
index 95db304fcf184bc266da42b727a7e944401f3e86..cf17941748782d9ee8d3f3bb4e735e8def43d964 100644
--- a/libobs/obs-properties.h
+++ b/libobs/obs-properties.h
@@ -286,10 +286,12 @@ EXPORT int obs_property_int_min(obs_property_t *p);
EXPORT int obs_property_int_max(obs_property_t *p);
EXPORT int obs_property_int_step(obs_property_t *p);
EXPORT enum obs_number_type obs_property_int_type(obs_property_t *p);
+EXPORT const char * obs_property_int_suffix(obs_property_t *p);
EXPORT double obs_property_float_min(obs_property_t *p);
EXPORT double obs_property_float_max(obs_property_t *p);
EXPORT double obs_property_float_step(obs_property_t *p);
EXPORT enum obs_number_type obs_property_float_type(obs_property_t *p);
+EXPORT const char * obs_property_float_suffix(obs_property_t *p);
EXPORT enum obs_text_type obs_property_text_type(obs_property_t *p);
EXPORT enum obs_path_type obs_property_path_type(obs_property_t *p);
EXPORT const char * obs_property_path_filter(obs_property_t *p);
@@ -301,6 +303,8 @@ EXPORT void obs_property_int_set_limits(obs_property_t *p,
int min, int max, int step);
EXPORT void obs_property_float_set_limits(obs_property_t *p,
double min, double max, double step);
+EXPORT void obs_property_int_set_suffix(obs_property_t *p, const char *suffix);
+EXPORT void obs_property_float_set_suffix(obs_property_t *p, const char *suffix);
EXPORT void obs_property_list_clear(obs_property_t *p);
diff --git a/plugins/mac-vth264/encoder.c b/plugins/mac-vth264/encoder.c
index b3f8b41ce352e36c5e5e37aa1afa8c602ac925ef..83137dd7df40827d04597a523908942e350ed9c2 100644
--- a/plugins/mac-vth264/encoder.c
+++ b/plugins/mac-vth264/encoder.c
@@ -874,14 +874,18 @@ static obs_properties_t *vt_h264_properties(void *unused)
obs_properties_t *props = obs_properties_create();
obs_property_t *p;
- obs_properties_add_int(props, "bitrate", TEXT_BITRATE, 50, 10000000, 50);
+ p = obs_properties_add_int(props, "bitrate",
+ TEXT_BITRATE, 50, 10000000, 50);
+ obs_property_int_set_suffix(p, " Kbps");
p = obs_properties_add_bool(props, "limit_bitrate",
TEXT_USE_MAX_BITRATE);
obs_property_set_modified_callback(p, limit_bitrate_modified);
- obs_properties_add_int(props, "max_bitrate", TEXT_MAX_BITRATE, 50,
+ p = obs_properties_add_int(props, "max_bitrate", TEXT_MAX_BITRATE, 50,
10000000, 50);
+ obs_property_int_set_suffix(p, " Kbps");
+
obs_properties_add_float(props, "max_bitrate_window",
TEXT_MAX_BITRATE_WINDOW, 0.10f, 10.0f, 0.25f);
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
index cddac7a12f171d3d33afe78e0127c07241a444ff..469dce4e09f8815106db1fea7e1eb56a17fa2ff7 100644
--- a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
@@ -451,10 +451,12 @@ obs_properties_t *nvenc_properties_internal(bool ffmpeg)
obs_property_set_modified_callback(p, rate_control_modified);
- obs_properties_add_int(props, "bitrate",
+ p = obs_properties_add_int(props, "bitrate",
obs_module_text("Bitrate"), 50, 300000, 50);
- obs_properties_add_int(props, "max_bitrate",
+ obs_property_int_set_suffix(p, " Kbps");
+ p = obs_properties_add_int(props, "max_bitrate",
obs_module_text("MaxBitrate"), 50, 300000, 50);
+ obs_property_int_set_suffix(p, " Kbps");
obs_properties_add_int(props, "cqp", obs_module_text("NVENC.CQLevel"),
1, 30, 1);
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
index 6b17ffe3d8206e96a3a544e6aa2d751bddd83f71..db861da23d1ff5067a3ee1e47c4d40b236fca99b 100644
--- a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
@@ -490,8 +490,10 @@ static obs_properties_t *vaapi_properties(void *unused)
obs_property_list_add_int(list, "720p60/1080p30 (4.1)", 41);
obs_property_list_add_int(list, "1080p60 (4.2)", 42);
- obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), 0,
+ obs_property_t *p;
+ p = obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), 0,
300000, 50);
+ obs_property_int_set_suffix(p, " Kbps");
obs_properties_add_int(props, "keyint_sec",
obs_module_text("Keyframe Interval (seconds)"), 0, 20,
diff --git a/plugins/obs-qsv11/obs-qsv11.c b/plugins/obs-qsv11/obs-qsv11.c
index 4caea89e7effe8572b9f58892da1dcf613f34f37..9669bdf3961f49ed64f1d2e46803f9b8fdc8f4ce 100644
--- a/plugins/obs-qsv11/obs-qsv11.c
+++ b/plugins/obs-qsv11/obs-qsv11.c
@@ -260,10 +260,15 @@ static obs_properties_t *obs_qsv_props(void *unused)
add_rate_controls(list, qsv_ratecontrols);
obs_property_set_modified_callback(list, rate_control_modified);
- obs_properties_add_int(props, "bitrate", TEXT_TARGET_BITRATE, 50,
+ obs_property_t *p;
+ p = obs_properties_add_int(props, "bitrate", TEXT_TARGET_BITRATE, 50,
10000000, 50);
- obs_properties_add_int(props, "max_bitrate", TEXT_MAX_BITRATE, 50,
+ obs_property_int_set_suffix(p, " Kbps");
+
+ p = obs_properties_add_int(props, "max_bitrate", TEXT_MAX_BITRATE, 50,
10000000, 50);
+ obs_property_int_set_suffix(p, " Kbps");
+
obs_properties_add_int(props, "accuracy", TEXT_ACCURACY, 0, 10000, 1);
obs_properties_add_int(props, "convergence", TEXT_CONVERGENCE, 0, 10, 1);
obs_properties_add_int(props, "qpi", "QPI", 1, 51, 1);
diff --git a/plugins/obs-x264/obs-x264.c b/plugins/obs-x264/obs-x264.c
index 6cd369dcf7d0a18deba65738076617a2be26da7a..6e0d2e67aadb600bf0a562b7f4e076fcd115a627 100644
--- a/plugins/obs-x264/obs-x264.c
+++ b/plugins/obs-x264/obs-x264.c
@@ -179,7 +179,9 @@ static obs_properties_t *obs_x264_props(void *unused)
obs_property_set_modified_callback(list, rate_control_modified);
- obs_properties_add_int(props, "bitrate", TEXT_BITRATE, 50, 10000000, 50);
+ p = obs_properties_add_int(props, "bitrate",
+ TEXT_BITRATE, 50, 10000000, 50);
+ obs_property_int_set_suffix(p, " Kbps");
p = obs_properties_add_bool(props, "use_bufsize", TEXT_CUSTOM_BUF);
obs_property_set_modified_callback(p, use_bufsize_modified);