Sfoglia il codice sorgente

UI: Replace themeID and style hints with class property

Warchamp7 1 anno fa
parent
commit
cb026964b0

+ 3 - 3
UI/adv-audio-control.cpp

@@ -95,7 +95,7 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
 	active->setText(isActive ? QTStr("Basic.Stats.Status.Active")
 				 : QTStr("Basic.Stats.Status.Inactive"));
 	if (isActive)
-		setThemeID(active, "error");
+		setClasses(active, "text-danger");
 	active->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
 
 	volume->setMinimum(MIN_DB - 0.1);
@@ -370,10 +370,10 @@ void OBSAdvAudioCtrl::SourceActiveChanged(bool isActive)
 {
 	if (isActive && obs_source_audio_active(source)) {
 		active->setText(QTStr("Basic.Stats.Status.Active"));
-		setThemeID(active, "error");
+		setClasses(active, "text-danger");
 	} else {
 		active->setText(QTStr("Basic.Stats.Status.Inactive"));
-		setThemeID(active, "");
+		setClasses(active, "");
 	}
 }
 

+ 80 - 111
UI/data/themes/System.obt

@@ -14,95 +14,110 @@
     author: 'Warchamp7';
 }
 
-/* We need to set back the icons, or the preview wont stick. */
+.bg-base {
+    background-color: #DCD9D7;
+}
+
+.text-heading {
+    font-size: 36px;
+    font-weight: bold;
+}
+
+.text-large {
+    font-size: 16px;
+}
+
+.text-bright {
+    color: var(--primary_light);
+}
 
-* [themeID="addIconSmall"] {
+/* We need to set back the icons, or the preview wont stick. */
+.icon-plus {
     qproperty-icon: url(:/res/images/plus.svg);
 }
 
-* [themeID="removeIconSmall"] {
+.icon-minus {
     qproperty-icon: url(:/res/images/minus.svg);
 }
 
-* [themeID="clearIconSmall"] {
-    qproperty-icon: url(:/res/images/entry-clear.svg);
+.icon-trash {
+    qproperty-icon: url(:/res/images/trash.svg);
 }
 
-* [themeID="propertiesIconSmall"] {
-    qproperty-icon: url(:/settings/images/settings/general.svg);
+.icon-clear {
+    qproperty-icon: url(:/res/images/entry-clear.svg);
 }
 
-* [themeID="configIconSmall"] {
-    qproperty-icon: url(:/settings/images/settings/general.svg);
+.icon-gear {
+    qproperty-icon: url(:/res/images/settings/general.svg);
 }
 
-* [themeID="upArrowIconSmall"] {
-    qproperty-icon: url(:/res/images/up.svg);
+.icon-dots-vert {
+    qproperty-icon: url(:/res/images/dots-vert.svg);
 }
 
-* [themeID="refreshIconSmall"] {
+.icon-refresh {
     qproperty-icon: url(:/res/images/refresh.svg);
 }
 
-* [themeID="downArrowIconSmall"] {
-    qproperty-icon: url(:/res/images/down.svg);
+.icon-cogs {
+    qproperty-icon: url(:/res/images/cogs.svg);
 }
 
-* [themeID="pauseIconSmall"] {
-    qproperty-icon: url(:/res/images/media-pause.svg);
+.icon-touch {
+    qproperty-icon: url(:/res/images/interact.svg);
 }
 
-* [themeID="menuIconSmall"] {
-    qproperty-icon: url(:res/images/dots-vert.svg);
+.icon-up {
+    qproperty-icon: url(:/res/images/up.svg);
 }
 
-* [themeID="cogsIcon"] {
-    qproperty-icon: url(:/res/images/cogs.svg);
+.icon-down {
+    qproperty-icon: url(:/res/images/down.svg);
 }
 
-* [themeID="filtersIcon"] {
+.icon-filter {
     qproperty-icon: url(:/res/images/filter.svg);
 }
 
+.icon-revert {
+    qproperty-icon: url(:res/images/revert.svg);
+}
+
 MuteCheckBox {
     outline: none;
 }
 
-MuteCheckBox::indicator:checked {
+.indicator-mute::indicator:checked {
     image: url(:/res/images/mute.svg);
 }
 
-MuteCheckBox::indicator:indeterminate {
-    image: url(theme:Dark/unassigned.svg);
+.indicator-mute::indicator:indeterminate {
+    image: url(:/res/images/unassigned.svg);
 }
 
-MuteCheckBox::indicator:unchecked {
+.indicator-mute::indicator:unchecked {
     image: url(:/settings/images/settings/audio.svg);
 }
 
-QCheckBox[sourceTreeSubItem=true] {
+.indicator-expand {
     background: transparent;
     outline: none;
 }
 
-QCheckBox[sourceTreeSubItem=true]::indicator {
+.indicator-expand::indicator {
     width: 10px;
     height: 10px;
 }
 
-QCheckBox[sourceTreeSubItem=true]::indicator:checked {
+.indicator-expand::indicator:checked {
     image: url(:/res/images/expand.svg);
 }
 
-QCheckBox[sourceTreeSubItem=true]::indicator:unchecked {
+.indicator-expand::indicator:unchecked {
     image: url(:/res/images/collapse.svg);
 }
 
-OBSHotkeyLabel[hotkeyPairHover=true] {
-    color: red;
-}
-
-
 /* Volume Control */
 
 VolumeMeter {
@@ -127,29 +142,16 @@ VolumeMeter {
 
 /* Label warning/error */
 
-QLabel#warningLabel {
+.text-warning {
     color: rgb(192, 128, 0);
-    font-weight: bold;
 }
 
-QLabel#errorLabel {
+.text-danger {
     color: rgb(192, 0, 0);
-    font-weight: bold;
 }
 
-* [themeID="warning"] {
-    color: rgb(192, 128, 0);
-    font-weight: bold;
-}
-
-* [themeID="error"] {
-    color: rgb(192, 0, 0);
-    font-weight: bold;
-}
-
-* [themeID="good"] {
+.text-success {
     color: rgb(0, 128, 0);
-    font-weight: bold;
 }
 
 /* macOS Separator Fix */
@@ -159,26 +161,6 @@ QMainWindow::separator {
     height: 4px;
 }
 
-/* About dialog */
-
-* [themeID="aboutName"] {
-    font-size: 36px;
-    font-weight: bold;
-}
-
-* [themeID="aboutVersion"] {
-    font-size: 16px;
-    margin-bottom: 20px;
-}
-
-* [themeID="aboutInfo"] {
-    margin-bottom: 20px;
-}
-
-* [themeID="aboutHLayout"] {
-    background-color: #DCD9D7;
-}
-
 /* Preview background color */
 
 OBSQTDisplay {
@@ -187,7 +169,7 @@ OBSQTDisplay {
 
 /* Preview/Program labels */
 
-* [themeID="previewProgramLabels"] {
+.label-preview-title {
     font-size: 18px;
     font-weight: bold;
     color: rgb(122,121,122);
@@ -211,40 +193,31 @@ OBSBasicSettings QListWidget::item {
     padding-bottom: 5px;
 }
 
-/* Locked CheckBox */
-
-QCheckBox[lockCheckBox=true] {
+.checkbox-icon {
     outline: none;
     background: transparent;
 }
 
-QCheckBox[lockCheckBox=true]::indicator:checked {
+/* Locked CheckBox */
+
+.indicator-lock::indicator:checked {
     image: url(:res/images/locked.svg);
 }
 
-QCheckBox[lockCheckBox=true]::indicator:unchecked {
+.indicator-lock::indicator:unchecked {
     image: url(:res/images/unlocked.svg);
 }
 
 /* Visibility CheckBox */
 
-QCheckBox[visibilityCheckBox=true] {
-    outline: none;
-    background: transparent;
-}
-
-QCheckBox[visibilityCheckBox=true]::indicator:checked {
+.indicator-visibility::indicator:checked {
     image: url(:res/images/visible.svg);
 }
 
-QCheckBox[visibilityCheckBox=true]::indicator:unchecked {
+.indicator-visibility::indicator:unchecked {
     image: url(:res/images/invisible.svg);
 }
 
-* [themeID="revertIcon"] {
-    qproperty-icon: url(:res/images/revert.svg);
-}
-
 OBSMissingFiles {
     qproperty-warningIcon: url(:res/images/alert.svg);
 }
@@ -279,28 +252,28 @@ SceneTree {
 
 /* Save icon */
 
-* [themeID="replayIconSmall"] {
+.icon-save {
     qproperty-icon: url(:res/images/save.svg);
 }
 
 /* Studio Mode T-Bar */
 
-QSlider[themeID="tBarSlider"] {
+.slider-tbar {
     height: 24px;
 }
 
-QSlider::groove:horizontal[themeID="tBarSlider"] {
+.slider-tbar::groove:horizontal {
     border: 1px solid #4c4c4c;
     height: 5px;
     background: #DCD9D7;
 }
 
-QSlider::sub-page:horizontal[themeID="tBarSlider"] {
+.slider-tbar::sub-page:horizontal {
     background: #DCD9D7;
     border: 1px solid #4c4c4c;
 }
 
-QSlider::handle:horizontal[themeID="tBarSlider"] {
+.slider-tbar::handle:horizontal {
     background-color: #4c4c4c;
     width: 12px;
     height: 24px;
@@ -312,10 +285,6 @@ QSlider::handle:horizontal[themeID="tBarSlider"] {
     padding: 3px 10px;
 }
 
-#contextContainer QPushButton[themeID2=contextBarButton] {
-    padding: 3px 6px;
-}
-
 #contextContainer QPushButton#sourcePropertiesButton {
     qproperty-icon: url(:/settings/images/settings/general.svg);
 }
@@ -330,28 +299,28 @@ QSlider::handle:horizontal[themeID="tBarSlider"] {
 
 /* Media icons */
 
-* [themeID="playIcon"] {
+.icon-media-play {
     qproperty-icon: url(:res/images/media/media_play.svg);
 }
 
-* [themeID="pauseIcon"] {
-    qproperty-icon: url(:/res/images/media/media_pause.svg);
+.icon-media-pause {
+    qproperty-icon: url(:res/images/media/media_pause.svg);
 }
 
-* [themeID="restartIcon"] {
-    qproperty-icon: url(:/res/images/media/media_restart.svg);
+.icon-media-restart {
+    qproperty-icon: url(:res/images/media/media_restart.svg);
 }
 
-* [themeID="stopIcon"] {
-    qproperty-icon: url(:/res/images/media/media_stop.svg);
+.icon-media-stop {
+    qproperty-icon: url(:res/images/media/media_stop.svg);
 }
 
-* [themeID="nextIcon"] {
-    qproperty-icon: url(:/res/images/media/media_next.svg);
+.icon-media-next {
+    qproperty-icon: url(:res/images/media/media_next.svg);
 }
 
-* [themeID="previousIcon"] {
-    qproperty-icon: url(:/res/images/media/media_previous.svg);
+.icon-media-prev {
+    qproperty-icon: url(:res/images/media/media_previous.svg);
 }
 
 /* YouTube Integration */
@@ -369,7 +338,7 @@ OBSYoutubeActions {
     border: 1px solid #777;
 }
 
-#ytEventList QLabel[isSelectedEvent=true] {
+#ytEventList .row-selected {
     background-color: #ccc;
     border: 1px solid #444;
 }
@@ -380,7 +349,7 @@ QCalendarWidget QToolButton {
 }
 
 #qt_calendar_monthbutton::menu-indicator {
-    image: url(theme:Dark/down.svg);
+    image: url(:/res/images/down.svg);
     subcontrol-position: right;
     padding-top: 2px;
     padding-right: 2px;
@@ -395,13 +364,13 @@ QCalendarWidget QToolButton {
 
 QCalendarWidget #qt_calendar_prevmonth {
     padding: 2px;
-    qproperty-icon: url(theme:Dark/left.svg);
+    qproperty-icon: url(:/res/images/left.svg);
     icon-size: 16px;
 }
 
 QCalendarWidget #qt_calendar_nextmonth {
     padding: 2px;
-    qproperty-icon: url(theme:Dark/right.svg);
+    qproperty-icon: url(:/res/images/right.svg);
     icon-size: 16px;
 }
 

+ 267 - 290
UI/data/themes/Yami.obt

@@ -85,20 +85,27 @@
     --danger: var(--red3);
 
     --text: var(--white1);
-    --text_light: rgb(214,214,214);
-    --text_muted: rgb(153,153,153);
+    --text_light: rgb(214, 214, 214);
+    --text_muted: rgb(153, 153, 153);
 
     --text_disabled: var(--text_muted);
-    --text_inactive: rgb(255,254,255);
+    --text_inactive: rgb(255, 254, 255);
 
     /* Layout */
     /* Configurable Values */
-    --font_base_value: 10;   /* TODO: Min 8, Max 12, Step 1 */
-    --spacing_base_value: 4; /* TODO: Min 2, Max 7, Step 1 */
-    --padding_base_value: 4; /* TODO: Min 0.25, Max 10, Step 2 */
 
-    --border_highlight: "transparent"; /* TODO: Better Accessibility focus state */
+    /* TODO: Min 8, Max 12, Step 1 */
+    --font_base_value: 10;
+
+    /* 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: Move Accessibilty Colors to Theme config system */
+    --border_highlight: "transparent";
 
     /* OS Fixes */
     --os_mac_font_base_value: 12;
@@ -191,8 +198,8 @@
 
     --separator_hover: var(--white1);
 
-    --highlight: rgb(42,130,218);
-    --highlight_inactive: rgb(25,28,34);
+    --highlight: rgb(42, 130, 218);
+    --highlight_inactive: rgb(25, 28, 34);
 
     /* Qt Palette variables can be set with the "palette_" prefix */
     --palette_window: var(--bg_window);
@@ -231,6 +238,146 @@
     */
 }
 
+/* --------------------- */
+/* General Styling Hints */
+
+/* Backgrounds */
+
+.bg_window {
+    background-color: var(--bg_window);
+}
+
+.bg-base {
+    background-color: var(--bg_base);
+}
+
+.text-heading {
+    font-size: var(--font_heading);
+    font-weight: bold;
+}
+
+.text-large {
+    font-size: var(--font_large);
+}
+
+.text-bright {
+    color: var(--primary_light);
+}
+
+.text-muted {
+    color: var(--text_muted);
+}
+
+.text-warning {
+    color: var(--warning);
+}
+
+.text-danger {
+    color: var(--danger);
+}
+
+.text-success {
+    color: var(--green3);
+}
+
+.frame-notice {
+    background: var(--bg_preview);
+    border-radius: var(--border_radius);
+    padding: var(--padding_xlarge) var(--padding_large);
+}
+
+.frame-notice QLabel {
+    padding: var(--padding_large) 0px;
+}
+
+/* Icon Overrides */
+
+.icon-plus {
+    qproperty-icon: url(theme:Dark/plus.svg);
+}
+
+.icon-minus {
+    qproperty-icon: url(theme:Dark/minus.svg);
+}
+
+.icon-trash {
+    qproperty-icon: url(theme:Dark/trash.svg);
+}
+
+.icon-clear {
+    qproperty-icon: url(theme:Dark/entry-clear.svg);
+}
+
+.icon-gear {
+    qproperty-icon: url(theme:Dark/settings/general.svg);
+}
+
+.icon-dots-vert {
+    qproperty-icon: url(theme:Dark/dots-vert.svg);
+}
+
+.icon-refresh {
+    qproperty-icon: url(theme:Dark/refresh.svg);
+}
+
+.icon-cogs {
+    qproperty-icon: url(theme:Dark/cogs.svg);
+}
+
+.icon-touch {
+    qproperty-icon: url(theme:Dark/interact.svg);
+}
+
+.icon-up {
+    qproperty-icon: url(theme:Dark/up.svg);
+}
+
+.icon-down {
+    qproperty-icon: url(theme:Dark/down.svg);
+}
+
+.icon-pause {
+    qproperty-icon: url(theme:Dark/media-pause.svg);
+}
+
+.icon-filter {
+    qproperty-icon: url(theme:Dark/filter.svg);
+}
+
+.icon-revert {
+    qproperty-icon: url(theme:Dark/revert.svg);
+}
+
+.icon-save {
+    qproperty-icon: url(theme:Dark/save.svg);
+}
+
+/* Media icons */
+
+.icon-media-play {
+    qproperty-icon: url(theme:Dark/media/media_play.svg);
+}
+
+.icon-media-pause {
+    qproperty-icon: url(theme:Dark/media/media_pause.svg);
+}
+
+.icon-media-restart {
+    qproperty-icon: url(theme:Dark/media/media_restart.svg);
+}
+
+.icon-media-stop {
+    qproperty-icon: url(theme:Dark/media/media_stop.svg);
+}
+
+.icon-media-next {
+    qproperty-icon: url(theme:Dark/media/media_next.svg);
+}
+
+.icon-media-prev {
+    qproperty-icon: url(theme:Dark/media/media_previous.svg);
+}
+
 /* Default widget style, we override only what is needed. */
 
 QWidget {
@@ -294,7 +441,12 @@ SourceTree QWidget {
     margin-bottom: 0;
 }
 
-* [frameShape="1"], * [frameShape="2"], * [frameShape="3"], * [frameShape="4"], * [frameShape="5"], * [frameShape="6"] {
+* [frameShape="1"],
+* [frameShape="2"],
+* [frameShape="3"],
+* [frameShape="4"],
+* [frameShape="5"],
+* [frameShape="6"] {
     border: 1px solid var(--bg_base);
 }
 
@@ -428,7 +580,7 @@ SceneTree::item:disabled:hover {
 QListWidget QLineEdit,
 SceneTree QLineEdit,
 SourceTree QLineEdit {
-    padding:  0;
+    padding: 0;
     padding-bottom: 1px;
     margin: 0;
     border: 1px solid var(--white1);
@@ -454,13 +606,13 @@ OBSBasicSettings QListWidget::item {
 }
 
 OBSBasicSettings QScrollBar:vertical {
-  width: var(--settings_scrollbar_size);
-  margin-left: 9px;
+    width: var(--settings_scrollbar_size);
+    margin-left: 9px;
 }
 
 OBSBasicSettings QScrollBar:horizontal {
-  height: var(--settings_scrollbar_size);
-  margin-top: 9px;
+    height: var(--settings_scrollbar_size);
+    margin-top: 9px;
 }
 
 /* Settings properties view */
@@ -643,9 +795,9 @@ QScrollBar::handle:disabled {
 /* Source Context Bar */
 
 #contextContainer {
-  background-color: var(--bg_base);
-  margin-top: 4px;
-  border-radius: var(--border_radius);
+    background-color: var(--bg_base);
+    margin-top: 4px;
+    border-radius: var(--border_radius);
 }
 
 #contextContainer QPushButton {
@@ -671,58 +823,6 @@ QToolBar {
     margin: var(--spacing_base) 0px;
 }
 
-* [themeID="addIconSmall"] {
-    qproperty-icon: url(theme:Dark/plus.svg);
-}
-
-* [themeID="removeIconSmall"] {
-    qproperty-icon: url(theme:Dark/trash.svg);
-}
-
-* [themeID="clearIconSmall"] {
-    qproperty-icon: url(theme:Dark/entry-clear.svg);
-}
-
-* [themeID="propertiesIconSmall"] {
-    qproperty-icon: url(theme:Dark/settings/general.svg);
-}
-
-* [themeID="configIconSmall"] {
-    qproperty-icon: url(theme:Dark/settings/general.svg);
-}
-
-* [themeID="menuIconSmall"] {
-    qproperty-icon: url(theme:Dark/dots-vert.svg);
-}
-
-* [themeID="refreshIconSmall"] {
-    qproperty-icon: url(theme:Dark/refresh.svg);
-}
-
-* [themeID="cogsIcon"] {
-    qproperty-icon: url(theme:Dark/cogs.svg);
-}
-
-#sourceInteractButton {
-    qproperty-icon: url(theme:Dark/interact.svg);
-}
-
-* [themeID="upArrowIconSmall"] {
-    qproperty-icon: url(theme:Dark/up.svg);
-}
-
-* [themeID="downArrowIconSmall"] {
-    qproperty-icon: url(theme:Dark/down.svg);
-}
-
-* [themeID="pauseIconSmall"] {
-    qproperty-icon: url(theme:Dark/media-pause.svg);
-}
-
-* [themeID="filtersIcon"] {
-    qproperty-icon: url(theme:Dark/filter.svg);
-}
-
 QToolBarExtension {
     background: var(--button_bg);
     min-width: 12px;
@@ -736,7 +836,8 @@ QToolBarExtension {
 
 /* Tab Widget */
 
-QTabWidget::pane { /* The tab widget frame */
+/* The tab widget frame */
+QTabWidget::pane {
     border-top: 4px solid var(--tab_bg);
 }
 
@@ -831,7 +932,7 @@ QDateTimeEdit:selected {
 
 QComboBox::drop-down,
 QDateTimeEdit::drop-down {
-    border:none;
+    border: none;
     border-left: 1px solid var(--grey6);
     width: var(--input_height);
 }
@@ -929,7 +1030,8 @@ QDoubleSpinBox:focus {
 QSpinBox::up-button,
 QDoubleSpinBox::up-button {
     subcontrol-origin: padding;
-    subcontrol-position: top right; /* position at the top right corner */
+    /* position at the top right corner */
+    subcontrol-position: top right;
 
     width: var(--input_height);
     height: var(--spinbox_button_height);
@@ -942,7 +1044,8 @@ QDoubleSpinBox::up-button {
 QSpinBox::down-button,
 QDoubleSpinBox::down-button {
     subcontrol-origin: padding;
-    subcontrol-position: bottom right; /* position at the top right corner */
+    /* position at the top right corner */
+    subcontrol-position: bottom right;
 
     width: var(--input_height);
     height: var(--spinbox_button_height);
@@ -1061,7 +1164,7 @@ QToolButton {
 }
 
 QToolButton,
-QPushButton[toolButton="true"] {
+.btn-tool {
     background-color: var(--button_bg);
     padding: var(--padding_base) var(--padding_base);
     margin: 0px var(--spacing_base);
@@ -1071,7 +1174,7 @@ QPushButton[toolButton="true"] {
 }
 
 QToolButton:last-child,
-QPushButton[toolButton="true"]:last-child {
+.btn-tool:last-child {
     margin-right: 0px;
 }
 
@@ -1086,10 +1189,10 @@ QPushButton:hover {
 
 QToolButton:hover,
 QToolButton:focus,
-QPushButton[toolButton="true"]:hover,
-QPushButton[toolButton="true"]:focus,
-MuteCheckBox::indicator:hover,
-MuteCheckBox::indicator: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);
 }
@@ -1115,8 +1218,8 @@ QPushButton:pressed:hover {
 
 QToolButton:pressed,
 QToolButton:pressed:hover,
-QPushButton[toolButton="true"]:pressed,
-QPushButton[toolButton="true"]:pressed:hover {
+.btn-tool:pressed,
+.btn-tool:pressed:hover {
     background-color: var(--button_bg_down);
     border-color: var(--button_border);
 }
@@ -1127,7 +1230,7 @@ QPushButton:disabled {
 }
 
 QToolButton:disabled,
-QPushButton[toolButton="true"]:disabled {
+.btn-tool:disabled {
     background-color: var(--button_bg_disabled);
     border-color: transparent;
 }
@@ -1193,13 +1296,15 @@ QSlider::handle {
 QSlider::handle:horizontal {
     height: 10px;
     width: 20px;
-    margin: -3px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */
+    /* Handle is placed by default on the contents rect of the groove. Expand outside the groove */
+    margin: -3px 0;
 }
 
 QSlider::handle:vertical {
     width: 10px;
     height: 20px;
-    margin: 0 -3px; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */
+    /* Handle is placed by default on the contents rect of the groove. Expand outside the groove */
+    margin: 0 -3px;
 }
 
 QSlider::handle:hover {
@@ -1327,7 +1432,7 @@ VolumeMeter {
     qproperty-foregroundNominalColor: var(--green2);
     qproperty-foregroundWarningColor: var(--yellow2);
     qproperty-foregroundErrorColor: var(--red2);
-    qproperty-magnitudeColor: rgb(0,0,0);
+    qproperty-magnitudeColor: rgb(0, 0, 0);
     qproperty-majorTickColor: var(--white1);
     qproperty-minorTickColor: var(--grey1);
 }
@@ -1373,67 +1478,6 @@ QHeaderView::section {
     margin-bottom: 2px;
 }
 
-OBSHotkeyLabel[hotkeyPairHover=true] {
-    color: var(--primary_light);
-}
-
-/* Label warning/error */
-
-QLabel#warningLabel {
-    color: var(--warning);
-    font-weight: bold;
-}
-
-QLabel#errorLabel {
-    color: var(--danger);
-    font-weight: bold;
-}
-
-* [themeID="warning"] {
-    color: var(--warning);
-    font-weight: bold;
-}
-
-* [themeID="error"] {
-    color: var(--danger);
-    font-weight: bold;
-}
-
-* [themeID="good"] {
-    color: var(--green3);
-    font-weight: bold;
-}
-
-QFrame [noticeFrame="true"] {
-    background: var(--bg_preview);
-    border-radius: var(--border_radius);
-    padding: var(--padding_xlarge) var(--padding_large);
-}
-
-QFrame [noticeFrame="true"] QLabel {
-    padding: var(--padding_large) 0px;
-}
-
-/* About dialog */
-
-* [themeID="aboutName"] {
-    font-size: var(--font_heading);
-    font-weight: bold;
-}
-
-* [themeID="aboutVersion"] {
-    font-size: var(--font_large);
-    margin-bottom: 20px;
-}
-
-* [themeID="aboutInfo"] {
-    margin-bottom: 20px;
-}
-
-* [themeID="aboutHLayout"] {
-    background-color: var(--bg_base);
-}
-
 /* Canvas / Preview background color */
 
 OBSQTDisplay {
@@ -1468,7 +1512,7 @@ OBSBasicFilters #widget_2 QPushButton {
 
 /* Preview/Program labels */
 
-* [themeID="previewProgramLabels"] {
+.label-preview-title {
     font-size: var(--font_xlarge);
     font-weight: bold;
     color: var(--text_light);
@@ -1490,9 +1534,6 @@ OBSBasicSettings {
 }
 
 /* Checkboxes */
-QCheckBox {
-
-}
 
 QCheckBox::indicator,
 QGroupBox::indicator {
@@ -1535,84 +1576,60 @@ QGroupBox::indicator:unchecked:disabled {
     image: url(theme:Yami/checkbox_unchecked_disabled.svg);
 }
 
-/* Locked CheckBox */
-
-QCheckBox[lockCheckBox=true] {
+/* Icon Checkboxes */
+.checkbox-icon {
     outline: none;
     background: transparent;
     max-width: var(--icon_base);
     max-height: var(--icon_base);
     padding: var(--padding_base);
+    margin-right: var(--spacing_large);
     border: 1px solid transparent;
-    margin-left: var(--spacing_large);
+    border-radius: 4px;
 }
 
-QCheckBox[lockCheckBox=true]::indicator {
+.checkbox-icon::indicator {
     width: var(--icon_base);
     height: var(--icon_base);
-    border-radius: 4px;
 }
 
-QCheckBox[lockCheckBox=true]::indicator:checked,
-QCheckBox[lockCheckBox=true]::indicator:checked:hover {
-    image: url(theme:Dark/locked.svg);
+.checkbox-icon:hover,
+.checkbox-icon:focus {
+    border-color: var(--primary_lighter);
 }
 
-QCheckBox[lockCheckBox=true]::indicator:unchecked,
-QCheckBox[lockCheckBox=true]::indicator:unchecked:hover {
-    image: url(:res/images/unlocked.svg);
-}
+/* Locked CheckBox */
 
-QCheckBox[lockCheckBox=true]:hover,
-QCheckBox[lockCheckBox=true]:focus {
-    border: 1px solid var(--border_highlight);
+.indicator-lock::indicator:checked,
+.indicator-lock::indicator:checked:hover {
+    image: url(theme:Dark/locked.svg);
 }
 
-/* Visibility CheckBox */
-
-QCheckBox[visibilityCheckBox=true] {
-    outline: none;
-    background: transparent;
-    max-width: var(--icon_base);
-    max-height: var(--icon_base);
-    padding: var(--padding_base);
-    border: 1px solid transparent;
-    margin-left: var(--spacing_large);
+.indicator-lock::indicator:unchecked,
+.indicator-lock::indicator:unchecked:hover {
+    image: url(:res/images/unlocked.svg);
 }
 
-QCheckBox[visibilityCheckBox=true]::indicator {
-    width: var(--icon_base);
-    height: var(--icon_base);
-    border-radius: 4px;
-}
+/* Visibility CheckBox */
 
-QCheckBox[visibilityCheckBox=true]::indicator:checked,
-QCheckBox[visibilityCheckBox=true]::indicator:checked:hover {
+.indicator-visibility::indicator:checked,
+.indicator-visibility::indicator:checked:hover {
     image: url(theme:Dark/visible.svg);
 }
 
-QCheckBox[visibilityCheckBox=true]::indicator:unchecked,
-QCheckBox[visibilityCheckBox=true]::indicator:unchecked:hover {
+.indicator-visibility::indicator:unchecked,
+.indicator-visibility::indicator:unchecked:hover {
     image: url(:res/images/invisible.svg);
 }
 
-QCheckBox[visibilityCheckBox=true]:hover,
-QCheckBox[visibilityCheckBox=true]:focus {
-    border: 1px solid var(--border_highlight);
-}
-
-* [themeID="revertIcon"] {
-    qproperty-icon: url(theme:Dark/revert.svg);
-}
-
 /* Mute CheckBox */
 
 MuteCheckBox {
     outline: none;
 }
 
-MuteCheckBox::indicator,
-MuteCheckBox::indicator:unchecked {
+.indicator-mute::indicator,
+.indicator-mute::indicator:unchecked {
     width: var(--icon_base);
     height: var(--icon_base);
     background-color: var(--button_bg);
@@ -1623,8 +1640,8 @@ MuteCheckBox::indicator:unchecked {
     icon-size: var(--icon_base);
 }
 
-MuteCheckBox::indicator:hover,
-MuteCheckBox::indicator:unchecked:hover {
+.indicator-mute::indicator:hover,
+.indicator-mute::indicator:unchecked:hover {
     background-color: var(--button_bg_hover);
     padding: var(--padding_base_border) var(--padding_base_border);
     margin: 0px;
@@ -1632,45 +1649,45 @@ MuteCheckBox::indicator:unchecked:hover {
     icon-size: var(--icon_base);
 }
 
-MuteCheckBox::indicator:pressed,
-MuteCheckBox::indicator:pressed:hover {
+.indicator-mute::indicator:pressed,
+.indicator-mute::indicator:pressed:hover {
     background-color: var(--button_bg_down);
     border-color: var(--button_border);
 }
 
-MuteCheckBox::indicator:checked {
+.indicator-mute::indicator:checked {
     image: url(theme:Dark/mute.svg);
 }
 
-MuteCheckBox::indicator:indeterminate {
+.indicator-mute::indicator:indeterminate {
     image: url(theme:Dark/unassigned.svg);
 }
 
-MuteCheckBox::indicator:unchecked {
+.indicator-mute::indicator:unchecked {
     image: url(theme:Dark/settings/audio.svg);
 }
 
-MuteCheckBox::indicator:unchecked:hover {
+.indicator-mute::indicator:unchecked:hover {
     image: url(theme:Dark/settings/audio.svg);
 }
 
-MuteCheckBox::indicator:unchecked:focus {
+.indicator-mute::indicator:unchecked:focus {
     image: url(theme:Dark/settings/audio.svg);
 }
 
-MuteCheckBox::indicator:checked:hover {
+.indicator-mute::indicator:checked:hover {
     image: url(theme:Dark/mute.svg);
 }
 
-MuteCheckBox::indicator:checked:focus {
+.indicator-mute::indicator:checked:focus {
     image: url(theme:Dark/mute.svg);
 }
 
-MuteCheckBox::indicator:checked:disabled {
+.indicator-mute::indicator:checked:disabled {
     image: url(theme:Dark/mute.svg);
 }
 
-MuteCheckBox::indicator:unchecked:disabled {
+.indicator-mute::indicator:unchecked:disabled {
     image: url(theme:Dark/settings/audio.svg);
 }
 
@@ -1687,10 +1704,6 @@ OBSHotkeyLabel {
     padding: 4px 0px;
 }
 
-OBSHotkeyLabel[hotkeyPairHover=true] {
-    color: var(--blue2);
-}
-
 OBSHotkeyWidget QPushButton {
     min-width: 16px;
     padding: var(--padding_base);
@@ -1701,38 +1714,16 @@ OBSHotkeyWidget QPushButton {
 
 /* Sources List Group Collapse Checkbox */
 
-QCheckBox[sourceTreeSubItem=true] {
-    background: transparent;
-    outline: none;
-    padding: 1px;
-    min-width: var(--icon_base);
-    min-height: var(--icon_base);
-}
-
-QCheckBox[sourceTreeSubItem=true]::indicator {
-    width: var(--icon_base);
-    height: var(--icon_base);
-    padding: 0px;
-    border: 1px solid transparent;
-    border-radius: 4px;
-    margin-left: -1px;
-}
-
-QCheckBox[sourceTreeSubItem=true]::indicator:checked,
-QCheckBox[sourceTreeSubItem=true]::indicator:checked:hover {
+.indicator-expand::indicator:checked,
+.indicator-expand::indicator:checked:hover {
     image: url(theme:Dark/expand.svg);
 }
 
-QCheckBox[sourceTreeSubItem=true]::indicator:unchecked,
-QCheckBox[sourceTreeSubItem=true]::indicator:unchecked:hover {
+.indicator-expand::indicator:unchecked,
+.indicator-expand::indicator:unchecked:hover {
     image: url(theme:Dark/collapse.svg);
 }
 
-QCheckBox[sourceTreeSubItem=true]::indicator:hover,
-QCheckBox[sourceTreeSubItem=true]::indicator:focus {
-    border: 1px solid var(--border_highlight);
-}
-
 /* Source Icons */
 
 OBSBasic {
@@ -1761,81 +1752,49 @@ SceneTree {
     qproperty-gridItemHeight: var(--input_height_base);
 }
 
-*[gridMode="true"] SceneTree::item {
+.list-grid SceneTree::item {
     color: var(--text);
     background-color: var(--button_bg);
     border-radius: var(--border_radius);
     margin: var(--spacing_base);
 }
 
-*[gridMode="true"] SceneTree::item:selected {
+.list-grid SceneTree::item:selected {
     background-color: var(--list_item_bg_selected);
 }
 
-*[gridMode="true"] SceneTree::item:checked {
+.list-grid SceneTree::item:checked {
     background-color: var(--primary);
 }
 
-*[gridMode="true"] SceneTree::item:hover {
+.list-grid SceneTree::item:hover {
     background-color: var(--list_item_bg_hover);
 }
 
-*[gridMode="true"] SceneTree::item:selected:hover {
+.list-grid SceneTree::item:selected:hover {
     background-color: var(--list_item_bg_hover);
 }
 
-/* Save icon */
-
-* [themeID="replayIconSmall"] {
-    qproperty-icon: url(theme:Dark/save.svg);
-}
-
 /* Studio Mode T-Bar */
 
-QSlider[themeID="tBarSlider"] {
+.slider-tbar {
     height: 24px;
 }
 
-QSlider::groove:horizontal[themeID="tBarSlider"] {
+.slider-tbar::groove:horizontal {
     height: 8px;
 }
 
-QSlider::sub-page:horizontal[themeID="tBarSlider"] {
+.slider-tbar::sub-page:horizontal {
     background: var(--blue2);
 }
 
-QSlider::handle:horizontal[themeID="tBarSlider"] {
+.slider-tbar::handle:horizontal {
     width: 12px;
     height: 24px;
     margin: -24px 0px;
 }
 
-/* Media icons */
-
-* [themeID="playIcon"] {
-    qproperty-icon: url(theme:Dark/media/media_play.svg);
-}
-
-* [themeID="pauseIcon"] {
-    qproperty-icon: url(theme:Dark/media/media_pause.svg);
-}
-
-* [themeID="restartIcon"] {
-    qproperty-icon: url(theme:Dark/media/media_restart.svg);
-}
-
-* [themeID="stopIcon"] {
-    qproperty-icon: url(theme:Dark/media/media_stop.svg);
-}
-
-* [themeID="nextIcon"] {
-    qproperty-icon: url(theme:Dark/media/media_next.svg);
-}
-
-* [themeID="previousIcon"] {
-    qproperty-icon: url(theme:Dark/media/media_previous.svg);
-}
-
 /* YouTube Integration */
 OBSYoutubeActions {
     qproperty-thumbPlaceholder: url(theme:Dark/sources/image.svg);
@@ -1853,12 +1812,12 @@ OBSYoutubeActions {
     background-color: var(--button_bg_hover);
 }
 
-#ytEventList QLabel[isSelectedEvent=true] {
+#ytEventList .row-selected {
     background-color: var(--primary);
     border: none;
 }
 
-#ytEventList QLabel[isSelectedEvent=true]:hover {
+#ytEventList .row-selected:hover {
     background-color: var(--primary_light);
     color: var(--text);
 }
@@ -1919,9 +1878,8 @@ QCalendarWidget QToolButton:pressed {
 }
 
 /* Month Dropdown Menu */
-QCalendarWidget QMenu {
+QCalendarWidget QMenu {}
 
-}
 /* Year spinbox */
 QCalendarWidget QSpinBox {
     background-color: var(--input_bg);
@@ -1931,13 +1889,32 @@ QCalendarWidget QSpinBox {
     padding: var(--padding_base) 16px;
 }
 
-QCalendarWidget QSpinBox::up-button { subcontrol-origin: border; subcontrol-position: top right; width: 16px; }
-QCalendarWidget QSpinBox::down-button {subcontrol-origin: border; subcontrol-position: bottom right; width: 16px;}
-QCalendarWidget QSpinBox::up-arrow { width: 10px; height: 10px; }
-QCalendarWidget QSpinBox::down-arrow { width: 10px; height: 10px; }
+QCalendarWidget QSpinBox::up-button {
+    subcontrol-origin: border;
+    subcontrol-position: top right;
+    width: 16px;
+}
+
+QCalendarWidget QSpinBox::down-button {
+    subcontrol-origin: border;
+    subcontrol-position: bottom right;
+    width: 16px;
+}
+
+QCalendarWidget QSpinBox::up-arrow {
+    width: 10px;
+    height: 10px;
+}
+
+QCalendarWidget QSpinBox::down-arrow {
+    width: 10px;
+    height: 10px;
+}
 
 /* Days of the Week Bar */
-QCalendarWidget QWidget { alternate-background-color: var(--grey7); }
+QCalendarWidget QWidget {
+    alternate-background-color: var(--grey7);
+}
 
 QCalendarWidget QAbstractItemView:enabled {
     background-color: var(--bg_base);

+ 4 - 4
UI/data/themes/Yami_Acri.ovt

@@ -187,19 +187,19 @@ OBSQTDisplay {
     qproperty-displayBackgroundColor: var(--grey5);
 }
 
-*[gridMode="true"] SceneTree::item:selected {
+.list-grid SceneTree::item:selected {
     background-color: var(--button_bg_red);
 }
 
-*[gridMode="true"] SceneTree::item:checked {
+.list-grid SceneTree::item:checked {
     background-color: var(--button_bg_red);
 }
 
-*[gridMode="true"] SceneTree::item:hover {
+.list-grid SceneTree::item:hover {
     background-color: var(--button_bg_red_down);
 }
 
-*[gridMode="true"] SceneTree::item:selected:hover {
+.list-grid SceneTree::item:selected:hover {
     background-color: var(--button_bg_red_hover);
 }
 

+ 25 - 29
UI/data/themes/Yami_Light.ovt

@@ -66,56 +66,56 @@ QPushButton#sourceFiltersButton {
     qproperty-icon: url(theme:Light/filter.svg);
 }
 
-* [themeID="addIconSmall"] {
+.icon-plus {
     qproperty-icon: url(theme:Light/plus.svg);
 }
 
-* [themeID="removeIconSmall"] {
-    qproperty-icon: url(theme:Light/trash.svg);
+.icon-minus {
+    qproperty-icon: url(theme:Light/minus.svg);
 }
 
-* [themeID="clearIconSmall"] {
-    qproperty-icon: url(theme:Light/entry-clear.svg);
+.icon-trash {
+    qproperty-icon: url(theme:Light/trash.svg);
 }
 
-* [themeID="propertiesIconSmall"] {
-    qproperty-icon: url(theme:Light/settings/general.svg);
+.icon-clear {
+    qproperty-icon: url(theme:Light/entry-clear.svg);
 }
 
-* [themeID="configIconSmall"] {
+.icon-gear {
     qproperty-icon: url(theme:Light/settings/general.svg);
 }
 
-* [themeID="menuIconSmall"] {
+.icon-dots-vert {
     qproperty-icon: url(theme:Light/dots-vert.svg);
 }
 
-* [themeID="refreshIconSmall"] {
+.icon-refresh {
     qproperty-icon: url(theme:Light/refresh.svg);
 }
 
-* [themeID="cogsIcon"] {
+.icon-cogs {
     qproperty-icon: url(theme:Light/cogs.svg);
 }
 
-#sourceInteractButton {
+.icon-touch {
     qproperty-icon: url(theme:Light/interact.svg);
 }
 
-* [themeID="upArrowIconSmall"] {
+.icon-up {
     qproperty-icon: url(theme:Light/up.svg);
 }
 
-* [themeID="downArrowIconSmall"] {
+.icon-down {
     qproperty-icon: url(theme:Light/down.svg);
 }
 
-* [themeID="pauseIconSmall"] {
-    qproperty-icon: url(theme:Light/media-pause.svg);
+.icon-filter {
+    qproperty-icon: url(theme:Light/filter.svg);
 }
 
-* [themeID="filtersIcon"] {
-    qproperty-icon: url(theme:Light/filter.svg);
+.icon-revert {
+    qproperty-icon: url(theme:Light/revert.svg);
 }
 
 QToolBarExtension {
@@ -196,10 +196,6 @@ QCheckBox[visibilityCheckBox=true]::indicator:checked:hover {
     image: url(theme:Light/visible.svg);
 }
 
-* [themeID="revertIcon"] {
-    qproperty-icon: url(theme:Light/revert.svg);
-}
-
 MuteCheckBox::indicator:checked {
     image: url(theme:Light/mute.svg);
 }
@@ -262,32 +258,32 @@ OBSBasic {
     qproperty-audioProcessOutputIcon: url(theme:Light/sources/windowaudio.svg);
 }
 
-* [themeID="replayIconSmall"] {
+.icon-save {
     qproperty-icon: url(theme:Light/save.svg);
 }
 
 /* Media icons */
-* [themeID="playIcon"] {
+.icon-media-play {
     qproperty-icon: url(theme:Light/media/media_play.svg);
 }
 
-* [themeID="pauseIcon"] {
+.icon-media-pause {
     qproperty-icon: url(theme:Light/media/media_pause.svg);
 }
 
-* [themeID="restartIcon"] {
+.icon-media-restart {
     qproperty-icon: url(theme:Light/media/media_restart.svg);
 }
 
-* [themeID="stopIcon"] {
+.icon-media-stop {
     qproperty-icon: url(theme:Light/media/media_stop.svg);
 }
 
-* [themeID="nextIcon"] {
+.icon-media-next {
     qproperty-icon: url(theme:Light/media/media_next.svg);
 }
 
-* [themeID="previousIcon"] {
+.icon-media-prev {
     qproperty-icon: url(theme:Light/media/media_previous.svg);
 }
 

+ 3 - 0
UI/forms/AutoConfigVideoPage.ui

@@ -74,6 +74,9 @@
      <property name="wordWrap">
       <bool>true</bool>
      </property>
+     <property name="class" stdset="0">
+      <string notr="true">text-warning</string>
+     </property>
     </widget>
    </item>
    <item>

+ 32 - 0
UI/forms/OBSAbout.ui

@@ -87,6 +87,22 @@
          </property>
         </widget>
        </item>
+       <item>
+        <spacer name="verticalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Fixed</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
        <item>
         <widget class="QLabel" name="info">
          <property name="text">
@@ -97,6 +113,22 @@
          </property>
         </widget>
        </item>
+       <item>
+        <spacer name="verticalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Fixed</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
        <item>
         <widget class="QLabel" name="contribute">
          <property name="text">

+ 34 - 40
UI/forms/OBSBasic.ui

@@ -198,8 +198,8 @@
              <property name="alignment">
               <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
              </property>
-             <property name="themeID" stdset="0">
-              <string>previewProgramLabels</string>
+             <property name="class" stdset="0">
+              <string>label-preview-title</string>
              </property>
             </widget>
            </item>
@@ -489,9 +489,6 @@
             <property name="flat">
              <bool>false</bool>
             </property>
-            <property name="themeID2" stdset="0">
-             <string notr="true">contextBarButton</string>
-            </property>
            </widget>
           </item>
           <item>
@@ -515,9 +512,6 @@
             <property name="flat">
              <bool>false</bool>
             </property>
-            <property name="themeID2" stdset="0">
-             <string notr="true">contextBarButton</string>
-            </property>
            </widget>
           </item>
           <item>
@@ -541,8 +535,8 @@
             <property name="flat">
              <bool>false</bool>
             </property>
-            <property name="themeID2" stdset="0">
-             <string notr="true">contextBarButton</string>
+            <property name="class" stdset="0">
+             <string notr="true">icon-touch</string>
             </property>
            </widget>
           </item>
@@ -1420,8 +1414,8 @@
             <property name="flat">
              <bool>false</bool>
             </property>
-            <property name="themeID" stdset="0">
-             <string notr="true">addIconSmall</string>
+            <property name="class" stdset="0">
+             <string notr="true">icon-plus</string>
             </property>
             <property name="toolButton" stdset="0">
              <bool>true</bool>
@@ -1452,8 +1446,8 @@
             <property name="flat">
              <bool>false</bool>
             </property>
-            <property name="themeID" stdset="0">
-             <string notr="true">removeIconSmall</string>
+            <property name="class" stdset="0">
+             <string notr="true">icon-trash</string>
             </property>
             <property name="toolButton" stdset="0">
              <bool>true</bool>
@@ -1484,8 +1478,8 @@
             <property name="flat">
              <bool>false</bool>
             </property>
-            <property name="themeID" stdset="0">
-             <string notr="true">menuIconSmall</string>
+            <property name="class" stdset="0">
+             <string notr="true">icon-dots-vert</string>
             </property>
             <property name="toolButton" stdset="0">
              <string notr="true">true</string>
@@ -1524,8 +1518,8 @@
    <property name="toolTip">
     <string>Basic.Main.AddSceneDlg.Title</string>
    </property>
-   <property name="themeID" stdset="0">
-    <string notr="true">addIconSmall</string>
+   <property name="class" stdset="0">
+    <string notr="true">icon-plus</string>
    </property>
   </action>
   <action name="actionAddSource">
@@ -1539,8 +1533,8 @@
    <property name="toolTip">
     <string>AddSource</string>
    </property>
-   <property name="themeID" stdset="0">
-    <string notr="true">addIconSmall</string>
+   <property name="class" stdset="0">
+    <string notr="true">icon-plus</string>
    </property>
   </action>
   <action name="actionRemoveScene">
@@ -1563,8 +1557,8 @@
    <property name="iconVisibleInMenu">
     <bool>false</bool>
    </property>
-   <property name="themeID" stdset="0">
-    <string notr="true">removeIconSmall</string>
+   <property name="class" stdset="0">
+    <string notr="true">icon-trash</string>
    </property>
   </action>
   <action name="actionRemoveSource">
@@ -1587,8 +1581,8 @@
    <property name="iconVisibleInMenu">
     <bool>false</bool>
    </property>
-   <property name="themeID" stdset="0">
-    <string notr="true">removeIconSmall</string>
+   <property name="class" stdset="0">
+    <string notr="true">icon-trash</string>
    </property>
   </action>
   <action name="actionSourceProperties">
@@ -1605,8 +1599,8 @@
    <property name="toolTip">
     <string>SourceProperties</string>
    </property>
-   <property name="themeID" stdset="0">
-    <string notr="true">propertiesIconSmall</string>
+   <property name="class" stdset="0">
+    <string notr="true">icon-gear</string>
    </property>
   </action>
   <action name="actionSceneUp">
@@ -1620,8 +1614,8 @@
    <property name="toolTip">
     <string>MoveSceneUp</string>
    </property>
-   <property name="themeID" stdset="0">
-    <string notr="true">upArrowIconSmall</string>
+   <property name="class" stdset="0">
+    <string notr="true">icon-up</string>
    </property>
   </action>
   <action name="actionSourceUp">
@@ -1638,8 +1632,8 @@
    <property name="toolTip">
     <string>MoveSourceUp</string>
    </property>
-   <property name="themeID" stdset="0">
-    <string notr="true">upArrowIconSmall</string>
+   <property name="class" stdset="0">
+    <string notr="true">icon-up</string>
    </property>
   </action>
   <action name="actionSceneDown">
@@ -1653,8 +1647,8 @@
    <property name="toolTip">
     <string>MoveSceneDown</string>
    </property>
-   <property name="themeID" stdset="0">
-    <string notr="true">downArrowIconSmall</string>
+   <property name="class" stdset="0">
+    <string notr="true">icon-down</string>
    </property>
   </action>
   <action name="actionSourceDown">
@@ -1671,8 +1665,8 @@
    <property name="toolTip">
     <string>MoveSourceDown</string>
    </property>
-   <property name="themeID" stdset="0">
-    <string notr="true">downArrowIconSmall</string>
+   <property name="class" stdset="0">
+    <string notr="true">icon-down</string>
    </property>
   </action>
   <action name="actionShow_Recordings">
@@ -2181,8 +2175,8 @@
    <property name="toolTip">
     <string>Basic.AdvAudio</string>
    </property>
-   <property name="themeID" stdset="0">
-    <string>cogsIcon</string>
+   <property name="class" stdset="0">
+    <string>icon-cogs</string>
    </property>
   </action>
   <action name="actionMixerToolbarMenu">
@@ -2193,8 +2187,8 @@
    <property name="text">
     <string>MixerToolbarMenu</string>
    </property>
-   <property name="themeID" stdset="0">
-    <string>menuIconSmall</string>
+   <property name="class" stdset="0">
+    <string>icon-dots-vert</string>
    </property>
   </action>
   <action name="actionSceneFilters">
@@ -2208,8 +2202,8 @@
    <property name="toolTip">
     <string>SceneFilters</string>
    </property>
-   <property name="themeID" stdset="0">
-    <string>filtersIcon</string>
+   <property name="class" stdset="0">
+    <string>icon-filter</string>
    </property>
   </action>
   <action name="actionSceneGridMode">

+ 6 - 6
UI/forms/OBSBasicControls.ui

@@ -164,8 +164,8 @@
           <property name="checkable">
            <bool>true</bool>
           </property>
-          <property name="themeID" stdset="0">
-           <string>pauseIconSmall</string>
+          <property name="class" stdset="0">
+           <string>icon-media-pause</string>
           </property>
          </widget>
         </item>
@@ -234,8 +234,8 @@
            <iconset resource="obs.qrc">
             <normaloff>:/res/images/save.svg</normaloff>:/res/images/save.svg</iconset>
           </property>
-          <property name="themeID" stdset="0">
-           <string>replayIconSmall</string>
+          <property name="class" stdset="0">
+           <string>icon-save</string>
           </property>
          </widget>
         </item>
@@ -304,8 +304,8 @@
            <iconset resource="obs.qrc">
             <normaloff>:/settings/images/settings/general.svg</normaloff>:/settings/images/settings/general.svg</iconset>
           </property>
-          <property name="themeID" stdset="0">
-           <string>configIconSmall</string>
+          <property name="class" stdset="0">
+           <string>icon-gear</string>
           </property>
          </widget>
         </item>

+ 16 - 16
UI/forms/OBSBasicFilters.ui

@@ -125,8 +125,8 @@
                <property name="flat">
                 <bool>true</bool>
                </property>
-               <property name="themeID" stdset="0">
-                <string>addIconSmall</string>
+               <property name="class" stdset="0">
+                <string>icon-plus</string>
                </property>
                <property name="toolButton" stdset="0">
                 <bool>true</bool>
@@ -157,8 +157,8 @@
                <property name="flat">
                 <bool>true</bool>
                </property>
-               <property name="themeID" stdset="0">
-                <string>removeIconSmall</string>
+               <property name="class" stdset="0">
+                <string>icon-trash</string>
                </property>
                <property name="toolButton" stdset="0">
                 <bool>true</bool>
@@ -189,8 +189,8 @@
                <property name="flat">
                 <bool>true</bool>
                </property>
-               <property name="themeID" stdset="0">
-                <string>upArrowIconSmall</string>
+               <property name="class" stdset="0">
+                <string>icon-up</string>
                </property>
                <property name="toolButton" stdset="0">
                 <bool>true</bool>
@@ -221,8 +221,8 @@
                <property name="flat">
                 <bool>true</bool>
                </property>
-               <property name="themeID" stdset="0">
-                <string>downArrowIconSmall</string>
+               <property name="class" stdset="0">
+                <string>icon-down</string>
                </property>
                <property name="toolButton" stdset="0">
                 <bool>true</bool>
@@ -359,8 +359,8 @@
                <property name="flat">
                 <bool>true</bool>
                </property>
-               <property name="themeID" stdset="0">
-                <string>addIconSmall</string>
+               <property name="class" stdset="0">
+                <string>icon-plus</string>
                </property>
                <property name="toolButton" stdset="0">
                 <bool>true</bool>
@@ -391,8 +391,8 @@
                <property name="flat">
                 <bool>true</bool>
                </property>
-               <property name="themeID" stdset="0">
-                <string>removeIconSmall</string>
+               <property name="class" stdset="0">
+                <string>icon-trash</string>
                </property>
                <property name="toolButton" stdset="0">
                 <bool>true</bool>
@@ -423,8 +423,8 @@
                <property name="flat">
                 <bool>true</bool>
                </property>
-               <property name="themeID" stdset="0">
-                <string>upArrowIconSmall</string>
+               <property name="class" stdset="0">
+                <string>icon-up</string>
                </property>
                <property name="toolButton" stdset="0">
                 <bool>true</bool>
@@ -455,8 +455,8 @@
                <property name="flat">
                 <bool>true</bool>
                </property>
-               <property name="themeID" stdset="0">
-                <string>downArrowIconSmall</string>
+               <property name="class" stdset="0">
+                <string>icon-down</string>
                </property>
                <property name="toolButton" stdset="0">
                 <bool>true</bool>

+ 19 - 22
UI/forms/OBSBasicSettings.ui

@@ -1980,8 +1980,8 @@
             </property>
             <item>
              <widget class="QFrame" name="multitrackVideoNoticeBox">
-              <property name="noticeFrame" stdset="0">
-               <bool>true</bool>
+              <property name="class" stdset="0">
+               <string notr="true">frame-notice</string>
               </property>
               <layout class="QVBoxLayout" name="multitrackVideoNoticeBoxLayout">
                <property name="leftMargin">
@@ -3991,12 +3991,12 @@
                                  <property name="text">
                                   <string>Basic.Settings.Output.Adv.FFmpeg.CustomModeWarning</string>
                                  </property>
-                                 <property name="themeID" stdset="0">
-                                  <string notr="true">warning</string>
-                                 </property>
                                  <property name="wordWrap">
                                   <bool>true</bool>
                                  </property>
+                                 <property name="class" stdset="0">
+                                  <string notr="true">text-warning</string>
+                                 </property>
                                 </widget>
                                </item>
                                <item row="1" column="0">
@@ -5420,8 +5420,8 @@
                          <property name="text">
                           <string>Basic.Settings.Output.ReplayBuffer.UnavailableCustomFFmpeg</string>
                          </property>
-                         <property name="themeID" stdset="0">
-                          <string>warning</string>
+                         <property name="class" stdset="0">
+                          <string>text-warning</string>
                          </property>
                         </widget>
                        </item>
@@ -6049,8 +6049,8 @@
            <property name="wordWrap">
             <bool>true</bool>
            </property>
-           <property name="themeID" stdset="0">
-            <string>error</string>
+           <property name="class" stdset="0">
+            <string>text-danger</string>
            </property>
           </widget>
          </item>
@@ -6062,8 +6062,8 @@
            <property name="wordWrap">
             <bool>true</bool>
            </property>
-           <property name="themeID" stdset="0">
-            <string notr="true">warning</string>
+           <property name="class" stdset="0">
+            <string notr="true">text-warning</string>
            </property>
           </widget>
          </item>
@@ -6454,8 +6454,8 @@
            <property name="wordWrap">
             <bool>true</bool>
            </property>
-           <property name="themeID" stdset="0">
-            <string>error</string>
+           <property name="class" stdset="0">
+            <string>text-danger</string>
            </property>
           </widget>
          </item>
@@ -6539,11 +6539,8 @@
              <property name="flat">
               <bool>false</bool>
              </property>
-             <property name="themeID" stdset="0">
-              <string>revertIcon</string>
-             </property>
-             <property name="toolButton" stdset="0">
-              <bool>true</bool>
+             <property name="class" stdset="0">
+              <string>btn-tool icon-revert</string>
              </property>
             </widget>
            </item>
@@ -8435,8 +8432,8 @@
               <property name="wordWrap">
                <bool>true</bool>
               </property>
-              <property name="themeID" stdset="0">
-               <string>error</string>
+              <property name="class" stdset="0">
+               <string>text-danger</string>
               </property>
              </widget>
             </item>
@@ -8448,8 +8445,8 @@
               <property name="wordWrap">
                <bool>true</bool>
               </property>
-              <property name="themeID" stdset="0">
-               <string>error</string>
+              <property name="class" stdset="0">
+               <string>text-danger</string>
               </property>
              </widget>
             </item>

+ 3 - 0
UI/forms/OBSBasicVCamConfig.ui

@@ -42,6 +42,9 @@
      <property name="text">
       <string>Basic.VCam.RestartWarning</string>
      </property>
+     <property name="class" stdset="0">
+      <string notr="true">text-warning</string>
+     </property>
     </widget>
    </item>
    <item>

+ 2 - 5
UI/forms/source-toolbar/browser-source-toolbar.ui

@@ -56,11 +56,8 @@
      <property name="flat">
       <bool>true</bool>
      </property>
-     <property name="themeID" stdset="0">
-      <string notr="true">refreshIconSmall</string>
-     </property>
-     <property name="themeID2" stdset="0">
-      <string notr="true">contextBarButton</string>
+     <property name="class" stdset="0">
+      <string notr="true">icon-refresh</string>
      </property>
     </widget>
    </item>

+ 0 - 12
UI/forms/source-toolbar/media-controls.ui

@@ -74,9 +74,6 @@
      <property name="flat">
       <bool>true</bool>
      </property>
-     <property name="themeID2" stdset="0">
-      <string notr="true">contextBarButton</string>
-     </property>
     </widget>
    </item>
    <item>
@@ -115,9 +112,6 @@
      <property name="flat">
       <bool>true</bool>
      </property>
-     <property name="themeID2" stdset="0">
-      <string notr="true">contextBarButton</string>
-     </property>
     </widget>
    </item>
    <item>
@@ -156,9 +150,6 @@
      <property name="flat">
       <bool>true</bool>
      </property>
-     <property name="themeID2" stdset="0">
-      <string notr="true">contextBarButton</string>
-     </property>
     </widget>
    </item>
    <item>
@@ -197,9 +188,6 @@
      <property name="flat">
       <bool>true</bool>
      </property>
-     <property name="themeID2" stdset="0">
-      <string notr="true">contextBarButton</string>
-     </property>
     </widget>
    </item>
    <item>

+ 4 - 4
UI/frontend-plugins/frontend-tools/forms/auto-scene-switcher.ui

@@ -76,8 +76,8 @@
        <property name="flat">
         <bool>true</bool>
        </property>
-       <property name="themeID" stdset="0">
-        <string notr="true">addIconSmall</string>
+       <property name="class" stdset="0">
+        <string notr="true">icon-plus</string>
        </property>
        <property name="toolButton" stdset="0">
         <bool>true</bool>
@@ -95,8 +95,8 @@
        <property name="flat">
         <bool>true</bool>
        </property>
-       <property name="themeID" stdset="0">
-        <string notr="true">removeIconSmall</string>
+       <property name="class" stdset="0">
+        <string notr="true">icon-trash</string>
        </property>
        <property name="toolButton" stdset="0">
         <bool>true</bool>

+ 6 - 6
UI/frontend-plugins/frontend-tools/forms/scripts.ui

@@ -83,8 +83,8 @@
              <property name="flat">
               <bool>true</bool>
              </property>
-             <property name="themeID" stdset="0">
-              <string notr="true">addIconSmall</string>
+             <property name="class" stdset="0">
+              <string notr="true">icon-plus</string>
              </property>
              <property name="toolButton" stdset="0">
               <bool>true</bool>
@@ -117,8 +117,8 @@
              <property name="flat">
               <bool>true</bool>
              </property>
-             <property name="themeID" stdset="0">
-              <string notr="true">removeIconSmall</string>
+             <property name="class" stdset="0">
+              <string notr="true">icon-trash</string>
              </property>
              <property name="toolButton" stdset="0">
               <bool>true</bool>
@@ -151,8 +151,8 @@
              <property name="flat">
               <bool>true</bool>
              </property>
-             <property name="themeID" stdset="0">
-              <string notr="true">refreshIconSmall</string>
+             <property name="class" stdset="0">
+              <string notr="true">icon-refresh</string>
              </property>
              <property name="toolButton" stdset="0">
               <bool>true</bool>

+ 6 - 6
UI/hotkey-edit.cpp

@@ -293,12 +293,12 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
 	edit->setToolTip(toolTip);
 
 	auto revert = new QPushButton;
-	revert->setProperty("themeID", "revertIcon");
+	revert->setProperty("class", "icon-revert");
 	revert->setToolTip(QTStr("Revert"));
 	revert->setEnabled(false);
 
 	auto clear = new QPushButton;
-	clear->setProperty("themeID", "clearIconSmall");
+	clear->setProperty("class", "icon-clear");
 	clear->setToolTip(QTStr("Clear"));
 	clear->setEnabled(!obs_key_combination_is_empty(combo));
 
@@ -311,11 +311,11 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
 		});
 
 	auto add = new QPushButton;
-	add->setProperty("themeID", "addIconSmall");
+	add->setProperty("class", "icon-plus");
 	add->setToolTip(QTStr("Add"));
 
 	auto remove = new QPushButton;
-	remove->setProperty("themeID", "removeIconSmall");
+	remove->setProperty("class", "icon-trash");
 	remove->setToolTip(QTStr("Remove"));
 	remove->setEnabled(removeButtons.size() > 0);
 
@@ -462,9 +462,9 @@ void OBSHotkeyLabel::highlightPair(bool highlight)
 	if (!pairPartner)
 		return;
 
-	pairPartner->setProperty("hotkeyPairHover", highlight);
+	pairPartner->setProperty("class", highlight ? "text-bright" : "");
 	updateStyle(pairPartner);
-	setProperty("hotkeyPairHover", highlight);
+	setProperty("class", highlight ? "text-bright" : "");
 	updateStyle(this);
 }
 

+ 7 - 7
UI/media-controls.cpp

@@ -48,10 +48,10 @@ MediaControls::MediaControls(QWidget *parent)
 	  ui(new Ui::MediaControls)
 {
 	ui->setupUi(this);
-	ui->playPauseButton->setProperty("themeID", "playIcon");
-	ui->previousButton->setProperty("themeID", "previousIcon");
-	ui->nextButton->setProperty("themeID", "nextIcon");
-	ui->stopButton->setProperty("themeID", "stopIcon");
+	ui->playPauseButton->setProperty("class", "icon-media-play");
+	ui->previousButton->setProperty("class", "icon-media-prev");
+	ui->nextButton->setProperty("class", "icon-media-next");
+	ui->stopButton->setProperty("class", "icon-media-stop");
 	setFocusPolicy(Qt::StrongFocus);
 
 	connect(&mediaTimer, &QTimer::timeout, this,
@@ -213,7 +213,7 @@ void MediaControls::StopMediaTimer()
 void MediaControls::SetPlayingState()
 {
 	ui->slider->setEnabled(true);
-	ui->playPauseButton->setProperty("themeID", "pauseIcon");
+	ui->playPauseButton->setProperty("class", "icon-media-pause");
 	ui->playPauseButton->style()->unpolish(ui->playPauseButton);
 	ui->playPauseButton->style()->polish(ui->playPauseButton);
 	ui->playPauseButton->setToolTip(
@@ -227,7 +227,7 @@ void MediaControls::SetPlayingState()
 
 void MediaControls::SetPausedState()
 {
-	ui->playPauseButton->setProperty("themeID", "playIcon");
+	ui->playPauseButton->setProperty("class", "icon-media-play");
 	ui->playPauseButton->style()->unpolish(ui->playPauseButton);
 	ui->playPauseButton->style()->polish(ui->playPauseButton);
 	ui->playPauseButton->setToolTip(
@@ -238,7 +238,7 @@ void MediaControls::SetPausedState()
 
 void MediaControls::SetRestartState()
 {
-	ui->playPauseButton->setProperty("themeID", "restartIcon");
+	ui->playPauseButton->setProperty("class", "icon-media-restart");
 	ui->playPauseButton->style()->unpolish(ui->playPauseButton);
 	ui->playPauseButton->style()->polish(ui->playPauseButton);
 	ui->playPauseButton->setToolTip(

+ 1 - 0
UI/mute-checkbox.hpp

@@ -9,6 +9,7 @@ public:
 	MuteCheckBox(QWidget *parent = nullptr) : QCheckBox(parent)
 	{
 		setTristate(true);
+		setProperty("class", "indicator-mute");
 	}
 
 protected:

+ 1 - 1
UI/scene-tree.cpp

@@ -16,7 +16,7 @@ SceneTree::SceneTree(QWidget *parent_) : QListWidget(parent_)
 
 void SceneTree::SetGridMode(bool grid)
 {
-	parent()->setProperty("gridMode", grid);
+	parent()->setProperty("class", grid ? "list-grid" : "");
 	gridMode = grid;
 
 	if (gridMode) {

+ 4 - 12
UI/source-tree.cpp

@@ -77,23 +77,19 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
 		iconLabel->setPixmap(pixmap);
 		iconLabel->setEnabled(sourceVisible);
 		iconLabel->setStyleSheet("background: none");
-		iconLabel->setProperty("TH_Source_Icon", true);
+		iconLabel->setProperty("class", "source-icon");
 	}
 
 	vis = new QCheckBox();
-	vis->setProperty("visibilityCheckBox", true);
-	vis->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+	vis->setProperty("class", "checkbox-icon indicator-visibility");
 	vis->setChecked(sourceVisible);
-	vis->setStyleSheet("background: none");
 	vis->setAccessibleName(QTStr("Basic.Main.Sources.Visibility"));
 	vis->setAccessibleDescription(
 		QTStr("Basic.Main.Sources.VisibilityDescription").arg(name));
 
 	lock = new QCheckBox();
-	lock->setProperty("lockCheckBox", true);
-	lock->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+	lock->setProperty("class", "checkbox-icon indicator-lock");
 	lock->setChecked(obs_sceneitem_locked(sceneitem));
-	lock->setStyleSheet("background: none");
 	lock->setAccessibleName(QTStr("Basic.Main.Sources.Lock"));
 	lock->setAccessibleDescription(
 		QTStr("Basic.Main.Sources.LockDescription").arg(name));
@@ -557,11 +553,7 @@ void SourceTreeItem::Update(bool force)
 
 	} else if (type == Type::Group) {
 		expand = new QCheckBox();
-		expand->setProperty("sourceTreeSubItem", true);
-		expand->setSizePolicy(QSizePolicy::Maximum,
-				      QSizePolicy::Maximum);
-		expand->setMaximumSize(10, 16);
-		expand->setMinimumSize(10, 0);
+		expand->setProperty("class", "checkbox-icon indicator-expand");
 #ifdef __APPLE__
 		expand->setAttribute(Qt::WA_LayoutUsesWidgetRect);
 #endif

+ 1 - 2
UI/visibility-item-widget.cpp

@@ -19,7 +19,7 @@ VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
 	bool enabled = obs_source_enabled(source);
 
 	vis = new QCheckBox();
-	vis->setProperty("visibilityCheckBox", true);
+	vis->setProperty("class", "checkbox-icon indicator-visibility");
 	vis->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
 	vis->setChecked(enabled);
 
@@ -32,7 +32,6 @@ VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
 	itemLayout->setContentsMargins(0, 0, 0, 0);
 
 	setLayout(itemLayout);
-	setStyleSheet("background-color: rgba(255, 255, 255, 0);");
 
 	connect(vis, &QCheckBox::clicked, [this](bool visible) {
 		obs_source_set_enabled(source, visible);

+ 1 - 1
UI/volume-control.cpp

@@ -260,7 +260,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
 
 	if (showConfig) {
 		config = new QPushButton(this);
-		config->setProperty("themeID", "menuIconSmall");
+		config->setProperty("class", "icon-dots-vert");
 		config->setAutoDefault(false);
 
 		config->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

+ 6 - 6
UI/window-basic-about.cpp

@@ -54,12 +54,12 @@ OBSAbout::OBSAbout(QWidget *parent) : QDialog(parent), ui(new Ui::OBSAbout)
 	ui->authors->setText("<a href='#'>" + QTStr("About.Authors") + "</a>");
 	ui->license->setText("<a href='#'>" + QTStr("About.License") + "</a>");
 
-	ui->name->setProperty("themeID", "aboutName");
-	ui->version->setProperty("themeID", "aboutVersion");
-	ui->about->setProperty("themeID", "aboutHLayout");
-	ui->authors->setProperty("themeID", "aboutHLayout");
-	ui->license->setProperty("themeID", "aboutHLayout");
-	ui->info->setProperty("themeID", "aboutInfo");
+	ui->name->setProperty("class", "text-heading");
+	ui->version->setProperty("class", "text-large");
+	ui->about->setProperty("class", "bg-base");
+	ui->authors->setProperty("class", "bg-base");
+	ui->license->setProperty("class", "bg-base");
+	ui->info->setProperty("class", "");
 
 	connect(ui->about, &ClickableLabel::clicked, this,
 		&OBSAbout::ShowAbout);

+ 4 - 4
UI/window-basic-main-transitions.cpp

@@ -768,7 +768,7 @@ void OBSBasic::CreateProgramOptions()
 	layout->setSpacing(4);
 
 	QPushButton *configTransitions = new QPushButton();
-	configTransitions->setProperty("themeID", "menuIconSmall");
+	configTransitions->setProperty("class", "icon-dots-vert");
 
 	QHBoxLayout *mainButtonLayout = new QHBoxLayout();
 	mainButtonLayout->setSpacing(2);
@@ -781,7 +781,7 @@ void OBSBasic::CreateProgramOptions()
 	quickTransitions->setSpacing(2);
 
 	QPushButton *addQuickTransition = new QPushButton();
-	addQuickTransition->setProperty("themeID", "addIconSmall");
+	addQuickTransition->setProperty("class", "icon-plus");
 
 	QLabel *quickTransitionsLabel = new QLabel(QTStr("QuickTransitions"));
 	quickTransitionsLabel->setSizePolicy(QSizePolicy::Expanding,
@@ -797,7 +797,7 @@ void OBSBasic::CreateProgramOptions()
 	tBar->setMinimum(0);
 	tBar->setMaximum(T_BAR_PRECISION - 1);
 
-	tBar->setProperty("themeID", "tBarSlider");
+	tBar->setProperty("class", "slider-tbar");
 
 	connect(tBar, &QSlider::valueChanged, this, &OBSBasic::TBarChanged);
 	connect(tBar, &QSlider::sliderReleased, this, &OBSBasic::TBarReleased);
@@ -1636,7 +1636,7 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
 			new QLabel(QTStr("StudioMode.ProgramSceneLabel"), this);
 		programLabel->setSizePolicy(QSizePolicy::Ignored,
 					    QSizePolicy::Preferred);
-		programLabel->setProperty("themeID", "previewProgramLabels");
+		programLabel->setProperty("class", "label-preview-title");
 
 		programWidget = new QWidget();
 		programLayout = new QVBoxLayout();

+ 7 - 5
UI/window-basic-settings.cpp

@@ -5266,8 +5266,9 @@ void OBSBasicSettings::AdvOutRecCheckWarnings()
 	if (!errorMsg.isEmpty() || !warningMsg.isEmpty()) {
 		advOutRecWarning = new QLabel(
 			errorMsg.isEmpty() ? warningMsg : errorMsg, this);
-		advOutRecWarning->setObjectName(
-			errorMsg.isEmpty() ? "warningLabel" : "errorLabel");
+		advOutRecWarning->setProperty("class", errorMsg.isEmpty()
+							       ? "text-warning"
+							       : "text-danger");
 		advOutRecWarning->setWordWrap(true);
 
 		ui->advOutRecInfoLayout->addWidget(advOutRecWarning);
@@ -5667,7 +5668,8 @@ void OBSBasicSettings::SimpleReplayBufferChanged()
 				QTStr(ESTIMATE_TOO_LARGE_STR)
 					.arg(QString::number(int(memMB)),
 					     QString::number(int(memMaxMB))));
-			ui->simpleRBEstimate->setObjectName("warningLabel");
+			ui->simpleRBEstimate->setProperty("class",
+							  "text-warning");
 		}
 	} else {
 		ui->simpleRBEstimate->setText(QTStr(ESTIMATE_UNKNOWN_STR));
@@ -5769,7 +5771,7 @@ void OBSBasicSettings::AdvReplayBufferChanged()
 				QTStr(ESTIMATE_TOO_LARGE_STR)
 					.arg(QString::number(int(memMB)),
 					     QString::number(int(memMaxMB))));
-			ui->advRBEstimate->setObjectName("warningLabel");
+			ui->advRBEstimate->setProperty("class", "text-warning");
 		}
 	} else {
 		ui->advRBMegsMax->setVisible(true);
@@ -6001,7 +6003,7 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged()
 		return;
 
 	simpleOutRecWarning = new QLabel(warning, this);
-	simpleOutRecWarning->setObjectName("warningLabel");
+	simpleOutRecWarning->setProperty("class", "text-warning");
 	simpleOutRecWarning->setWordWrap(true);
 	ui->simpleOutInfoLayout->addWidget(simpleOutRecWarning);
 }

+ 22 - 22
UI/window-basic-stats.cpp

@@ -305,11 +305,11 @@ void OBSBasicStats::Update()
 	fps->setText(str);
 
 	if (curFPS < (obsFPS * 0.8))
-		setThemeID(fps, "error");
+		setClasses(fps, "text-danger");
 	else if (curFPS < (obsFPS * 0.95))
-		setThemeID(fps, "warning");
+		setClasses(fps, "text-warning");
 	else
-		setThemeID(fps, "");
+		setClasses(fps, "");
 
 	/* ------------------ */
 
@@ -341,11 +341,11 @@ void OBSBasicStats::Update()
 	hddSpace->setText(str);
 
 	if (num_bytes < GBYTE)
-		setThemeID(hddSpace, "error");
+		setClasses(hddSpace, "text-danger");
 	else if (num_bytes < (5 * GBYTE))
-		setThemeID(hddSpace, "warning");
+		setClasses(hddSpace, "text-warning");
 	else
-		setThemeID(hddSpace, "");
+		setClasses(hddSpace, "");
 
 	/* ------------------ */
 
@@ -365,11 +365,11 @@ void OBSBasicStats::Update()
 		(long double)ovi.fps_den * 1000.0l / (long double)ovi.fps_num;
 
 	if (num > fpsFrameTime)
-		setThemeID(renderTime, "error");
+		setClasses(renderTime, "text-danger");
 	else if (num > fpsFrameTime * 0.75l)
-		setThemeID(renderTime, "warning");
+		setClasses(renderTime, "text-warning");
 	else
-		setThemeID(renderTime, "");
+		setClasses(renderTime, "");
 
 	/* ------------------ */
 
@@ -396,11 +396,11 @@ void OBSBasicStats::Update()
 	skippedFrames->setText(str);
 
 	if (num > 5.0l)
-		setThemeID(skippedFrames, "error");
+		setClasses(skippedFrames, "text-danger");
 	else if (num > 1.0l)
-		setThemeID(skippedFrames, "warning");
+		setClasses(skippedFrames, "text-warning");
 	else
-		setThemeID(skippedFrames, "");
+		setClasses(skippedFrames, "");
 
 	/* ------------------ */
 
@@ -423,11 +423,11 @@ void OBSBasicStats::Update()
 	missedFrames->setText(str);
 
 	if (num > 5.0l)
-		setThemeID(missedFrames, "error");
+		setClasses(missedFrames, "text-danger");
 	else if (num > 1.0l)
-		setThemeID(missedFrames, "warning");
+		setClasses(missedFrames, "text-warning");
 	else
-		setThemeID(missedFrames, "");
+		setClasses(missedFrames, "");
 
 	/* ------------------------------------------- */
 	/* recording/streaming stats                   */
@@ -521,7 +521,7 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec)
 		kbps = 0.0l;
 
 	QString str = QTStr("Basic.Stats.Status.Inactive");
-	QString themeID;
+	QString styling;
 	bool active = output ? obs_output_active(output) : false;
 	if (rec) {
 		if (active)
@@ -534,16 +534,16 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec)
 
 			if (reconnecting) {
 				str = QTStr("Basic.Stats.Status.Reconnecting");
-				themeID = "error";
+				styling = "text-danger";
 			} else {
 				str = QTStr("Basic.Stats.Status.Live");
-				themeID = "good";
+				styling = "text-success";
 			}
 		}
 	}
 
 	status->setText(str);
-	setThemeID(status, themeID);
+	setClasses(status, styling);
 
 	long double num = (long double)totalBytes / (1024.0l * 1024.0l);
 	const char *unit = "MiB";
@@ -584,11 +584,11 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec)
 		droppedFrames->setText(str);
 
 		if (num > 5.0l)
-			setThemeID(droppedFrames, "error");
+			setClasses(droppedFrames, "text-danger");
 		else if (num > 1.0l)
-			setThemeID(droppedFrames, "warning");
+			setClasses(droppedFrames, "text-warning");
 		else
-			setThemeID(droppedFrames, "");
+			setClasses(droppedFrames, "");
 	}
 
 	lastBytesSent = bytesSent;

+ 1 - 1
UI/window-extra-browsers.cpp

@@ -135,7 +135,7 @@ void ExtraBrowsersModel::AddDeleteButton(int idx)
 	QModelIndex index = createIndex(idx, (int)Column::Delete, nullptr);
 
 	QPushButton *del = new DelButton(index);
-	del->setProperty("themeID", "removeIconSmall");
+	del->setProperty("class", "icon-trash");
 	del->setObjectName("extraPanelDelete");
 	del->setMinimumSize(QSize(20, 20));
 	connect(del, &QPushButton::clicked, this,

+ 3 - 5
UI/window-youtube-actions.cpp

@@ -262,14 +262,12 @@ OBSYoutubeActions::OBSYoutubeActions(QWidget *parent, Auth *auth,
 						     QString(),
 						     Qt::FindDirectChildrenOnly)) {
 
-						i->setProperty(
-							"isSelectedEvent",
-							"false");
+						i->setProperty("class", "");
 						i->style()->unpolish(i);
 						i->style()->polish(i);
 					}
-					label->setProperty("isSelectedEvent",
-							   "true");
+					label->setProperty("class",
+							   "row-selected");
 					label->style()->unpolish(label);
 					label->style()->polish(label);
 

+ 11 - 20
shared/properties-view/properties-view.cpp

@@ -394,9 +394,9 @@ QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout,
 		info_label->setWordWrap(obs_property_text_info_word_wrap(prop));
 
 		if (info_type == OBS_TEXT_INFO_WARNING)
-			info_label->setObjectName("warningLabel");
+			info_label->setProperty("class", "text-warning");
 		else if (info_type == OBS_TEXT_INFO_ERROR)
-			info_label->setObjectName("errorLabel");
+			info_label->setProperty("class", "text-danger");
 
 		if (label)
 			label->setObjectName(info_label->objectName());
@@ -431,7 +431,6 @@ void OBSPropertiesView::AddPath(obs_property_t *prop, QFormLayout *layout,
 		button->setEnabled(false);
 	}
 
-	button->setProperty("themeID", "settingsButtons");
 	edit->setText(QT_UTF8(val));
 	edit->setReadOnly(true);
 	edit->setToolTip(QT_UTF8(obs_property_long_description(prop)));
@@ -742,7 +741,7 @@ static void NewButton(QLayout *layout, WidgetInfo *info, const char *themeIcon,
 		      void (WidgetInfo::*method)())
 {
 	QPushButton *button = new QPushButton();
-	button->setProperty("themeID", themeIcon);
+	button->setProperty("class", themeIcon);
 	button->setFlat(true);
 	button->setProperty("toolButton", true);
 
@@ -790,15 +789,11 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
 		[info]() { info->EditableListChanged(); });
 
 	QVBoxLayout *sideLayout = new QVBoxLayout();
-	NewButton(sideLayout, info, "addIconSmall", &WidgetInfo::EditListAdd);
-	NewButton(sideLayout, info, "removeIconSmall",
-		  &WidgetInfo::EditListRemove);
-	NewButton(sideLayout, info, "configIconSmall",
-		  &WidgetInfo::EditListEdit);
-	NewButton(sideLayout, info, "upArrowIconSmall",
-		  &WidgetInfo::EditListUp);
-	NewButton(sideLayout, info, "downArrowIconSmall",
-		  &WidgetInfo::EditListDown);
+	NewButton(sideLayout, info, "icon-plus", &WidgetInfo::EditListAdd);
+	NewButton(sideLayout, info, "icon-trash", &WidgetInfo::EditListRemove);
+	NewButton(sideLayout, info, "icon-gear", &WidgetInfo::EditListEdit);
+	NewButton(sideLayout, info, "icon-up", &WidgetInfo::EditListUp);
+	NewButton(sideLayout, info, "icon-down", &WidgetInfo::EditListDown);
 	sideLayout->addStretch(0);
 
 	QHBoxLayout *subLayout = new QHBoxLayout();
@@ -816,7 +811,6 @@ QWidget *OBSPropertiesView::AddButton(obs_property_t *prop)
 	const char *desc = obs_property_description(prop);
 
 	QPushButton *button = new QPushButton(QT_UTF8(desc));
-	button->setProperty("themeID", "settingsButtons");
 	button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
 	return NewWidget(prop, button, &QPushButton::clicked);
 }
@@ -837,7 +831,6 @@ void OBSPropertiesView::AddColorInternal(obs_property_t *prop,
 		colorLabel->setEnabled(false);
 	}
 
-	button->setProperty("themeID", "settingsButtons");
 	button->setText(tr("Basic.PropertiesWindow.SelectColor"));
 	button->setToolTip(QT_UTF8(obs_property_long_description(prop)));
 
@@ -939,7 +932,6 @@ void OBSPropertiesView::AddFont(obs_property_t *prop, QFormLayout *layout,
 	font = fontLabel->font();
 	MakeQFont(font_obj, font, true);
 
-	button->setProperty("themeID", "settingsButtons");
 	button->setText(tr("Basic.PropertiesWindow.SelectFont"));
 	button->setToolTip(QT_UTF8(obs_property_long_description(prop)));
 
@@ -1413,7 +1405,7 @@ static void UpdateFPSLabels(OBSFrameRatePropertyWidget *w)
 		w->currentFPS->setHidden(true);
 		w->timePerFrame->setHidden(true);
 		if (!option)
-			w->warningLabel->setObjectName("errorLabel");
+			w->warningLabel->setProperty("class", "text-danger");
 
 		return;
 	}
@@ -1423,9 +1415,9 @@ static void UpdateFPSLabels(OBSFrameRatePropertyWidget *w)
 
 	media_frames_per_second match{};
 	if (!option && !matches_ranges(match, *valid_fps, w->fps_ranges, true))
-		w->warningLabel->setObjectName("errorLabel");
+		w->warningLabel->setProperty("class", "text-danger");
 	else
-		w->warningLabel->setObjectName("");
+		w->warningLabel->setProperty("class", "");
 
 	auto convert_to_fps = media_frames_per_second_to_fps;
 	auto convert_to_frame_interval =
@@ -2235,7 +2227,6 @@ public:
 		if (browse) {
 			QPushButton *browseButton =
 				new QPushButton(tr("Browse"));
-			browseButton->setProperty("themeID", "settingsButtons");
 			topLayout->addWidget(browseButton);
 			topLayout->setAlignment(browseButton, Qt::AlignVCenter);
 

+ 3 - 4
shared/qt/icon-label/icon-label.hpp

@@ -22,10 +22,9 @@
 
 /**
  * Widget to be used if a label is to be supplied a QIcon instead of a QPixmap,
- * specifically so that qproperty-icon QSS styling (and as a result the OBS
- * "themeID" property) works on it without having to first convert the icon to
- * a fixed size PNG and then setting qproperty-pixmap in addition to the
- * qproperty-icon statements.
+ * specifically so that qproperty-icon QSS styling works on it without having to
+ * first convert the icon to a fixed size PNG and then setting qproperty-pixmap
+ * in addition to the qproperty-icon statements.
  */
 class IconLabel : public QLabel {
 	Q_OBJECT

+ 3 - 3
shared/qt/wrappers/qt-wrappers.cpp

@@ -317,10 +317,10 @@ void SetComboItemEnabled(QComboBox *c, int idx, bool enabled)
 			       : Qt::NoItemFlags);
 }
 
-void setThemeID(QWidget *widget, const QString &themeID)
+void setClasses(QWidget *widget, const QString &newClasses)
 {
-	if (widget->property("themeID").toString() != themeID) {
-		widget->setProperty("themeID", themeID);
+	if (widget->property("class").toString() != newClasses) {
+		widget->setProperty("class", newClasses);
 
 		/* force style sheet recalculation */
 		QString qss = widget->styleSheet();

+ 1 - 1
shared/qt/wrappers/qt-wrappers.hpp

@@ -98,7 +98,7 @@ bool LineEditChanged(QEvent *event);
 
 void SetComboItemEnabled(QComboBox *c, int idx, bool enabled);
 
-void setThemeID(QWidget *widget, const QString &themeID);
+void setClasses(QWidget *widget, const QString &newClasses);
 
 QString SelectDirectory(QWidget *parent, QString title, QString path);
 QString SaveFile(QWidget *parent, QString title, QString path,