UI: Add Vertical Mixer option
parent
288339ceda
commit
c7c328dc83
|
@ -161,6 +161,7 @@ set(obs_SOURCES
|
|||
item-widget-helpers.cpp
|
||||
visibility-checkbox.cpp
|
||||
locked-checkbox.cpp
|
||||
horizontal-scroll-area.cpp
|
||||
vertical-scroll-area.cpp
|
||||
visibility-item-widget.cpp
|
||||
slider-absoluteset-style.cpp
|
||||
|
@ -209,6 +210,7 @@ set(obs_HEADERS
|
|||
item-widget-helpers.hpp
|
||||
visibility-checkbox.hpp
|
||||
locked-checkbox.hpp
|
||||
horizontal-scroll-area.hpp
|
||||
vertical-scroll-area.hpp
|
||||
visibility-item-widget.hpp
|
||||
slider-absoluteset-style.hpp
|
||||
|
|
|
@ -83,6 +83,7 @@ None="None"
|
|||
StudioMode.Preview="Preview"
|
||||
StudioMode.Program="Program"
|
||||
ShowInMultiview="Show in Multiview"
|
||||
VerticalLayout="Vertical Layout"
|
||||
|
||||
# warning if program already open
|
||||
AlreadyRunning.Title="OBS is already running"
|
||||
|
|
|
@ -505,16 +505,20 @@ QSlider::handle:horizontal {
|
|||
}
|
||||
|
||||
QSlider::handle:horizontal:pressed {
|
||||
background-color: QLinearGradient(x1: 0, y1: 1, x2: 0, y2: 0,
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(240,239,240),
|
||||
stop: 0.25 rgb(200,199,200),
|
||||
stop: 1 rgb(162,161,162));
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal {
|
||||
background-color: #2a3a75;
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal:disabled {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(31,30,31),
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
background-color: QLinearGradient(x1: 0, y1: 1, x2: 0, y2: 0,
|
||||
stop: 0 rgb(26,25,26),
|
||||
stop: 0.75 rgb(10, 10, 10));
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
|
@ -533,23 +537,27 @@ QSlider::handle:vertical {
|
|||
stop: 0.25 rgb(200,199,200),
|
||||
stop: 1 rgb(162,161,162));
|
||||
border: 1px solid rgb(24,24,25);
|
||||
border-radius: 4px;
|
||||
border-radius: 3px;
|
||||
width: 10px;
|
||||
height: 18px;
|
||||
margin: -3px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */
|
||||
margin: 0 -3px; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */
|
||||
}
|
||||
|
||||
QSlider::handle:vertical:pressed {
|
||||
background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0,
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
|
||||
stop: 0 rgb(240,239,240),
|
||||
stop: 0.25 rgb(200,199,200),
|
||||
stop: 1 rgb(162,161,162));
|
||||
}
|
||||
|
||||
QSlider::sub-page:vertical:disabled {
|
||||
QSlider::add-page:vertical {
|
||||
background-color: #2a3a75;
|
||||
}
|
||||
|
||||
QSlider::add-page:vertical:disabled {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
|
||||
stop: 0 rgb(31,30,31),
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
stop: 0 rgb(26,25,26),
|
||||
stop: 0.75 rgb(10, 10, 10));
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
|
@ -557,15 +565,10 @@ QSlider::handle:hover {
|
|||
background-color: rgb(200,199,200);
|
||||
}
|
||||
|
||||
QSlider::sub-page {
|
||||
background-color: #2a3a75;
|
||||
}
|
||||
|
||||
QSlider::handle:disabled {
|
||||
background-color: rgb(15,15,16);
|
||||
}
|
||||
|
||||
|
||||
/* Volume Control */
|
||||
|
||||
/* Old Meters */
|
||||
|
|
|
@ -423,9 +423,9 @@ QPushButton::menu-indicator {
|
|||
/* Sliders */
|
||||
|
||||
QSlider::groove:horizontal {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(31,30,31), /* veryDark */
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
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 */
|
||||
height: 4px;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
|
@ -450,32 +450,37 @@ QSlider::handle:horizontal:pressed {
|
|||
stop: 1 rgb(162,161,162)); /* light */
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal {
|
||||
background-color: rgb(42,130,218); /* blue */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal:disabled {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
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));
|
||||
stop: 0.75 rgb(50, 49, 50)); /* dark */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::groove:vertical {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
|
||||
stop: 0 rgb(31,30,31), /* veryDark */
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
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 */
|
||||
width: 4px;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::handle:vertical {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
|
||||
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 */
|
||||
border-radius: 4px;
|
||||
border-radius: 3px;
|
||||
width: 10px;
|
||||
height: 18px;
|
||||
margin: -3px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */
|
||||
margin: 0 -3px; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */
|
||||
}
|
||||
|
||||
QSlider::handle:vertical:pressed {
|
||||
|
@ -485,10 +490,15 @@ QSlider::handle:vertical:pressed {
|
|||
stop: 1 rgb(162,161,162)); /* light */
|
||||
}
|
||||
|
||||
QSlider::sub-page:vertical:disabled {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
|
||||
QSlider::add-page:vertical {
|
||||
background-color: rgb(42,130,218); /* blue */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
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));
|
||||
stop: 0.75 rgb(50, 49, 50)); /* dark */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
|
@ -496,16 +506,10 @@ QSlider::handle:hover {
|
|||
background-color: rgb(200,199,200); /* veryLight */
|
||||
}
|
||||
|
||||
QSlider::sub-page {
|
||||
background-color: rgb(42,130,218); /* blue */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::handle:disabled {
|
||||
background-color: rgb(122,121,122); /* light */
|
||||
}
|
||||
|
||||
|
||||
/* Volume Control */
|
||||
|
||||
VolumeMeter {
|
||||
|
|
|
@ -1022,10 +1022,55 @@ QSlider::handle:horizontal:pressed {
|
|||
stop: 1 rgb(162, 161, 162));
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal {
|
||||
background-color: rgb(0, 188, 212); /* Cyan (Primary) */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal:disabled {
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(35, 38, 41), /* Dark Gray */
|
||||
stop: 0.75 rgb(35, 38, 41)); /* Dark Gray */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::groove:vertical {
|
||||
background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0,
|
||||
stop: 0 rgb(35, 38, 41), /* Dark Gray */
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
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),
|
||||
stop: 0.25 rgb(200, 199, 200),
|
||||
stop: 1 rgb(162, 161, 162));
|
||||
border: 1px solid rgb(58, 57, 58);
|
||||
border-radius: 3px;
|
||||
width: 10px;
|
||||
height: 18px;
|
||||
margin: 0 -3px;
|
||||
}
|
||||
|
||||
QSlider::handle:vertical:pressed {
|
||||
background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0,
|
||||
stop: 0 rgb(240, 239, 240),
|
||||
stop: 0.25 rgb(200, 199, 200),
|
||||
stop: 1 rgb(162, 161, 162));
|
||||
}
|
||||
|
||||
QSlider::add-page:vertical {
|
||||
background-color: rgb(0, 188, 212); /* Cyan (Primary) */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::add-page:vertical:disabled {
|
||||
background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0,
|
||||
stop: 0 rgb(35, 38, 41), /* Dark Gray */
|
||||
stop: 0.75 rgb(35, 38, 41)); /* Dark Gray */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
|
@ -1033,11 +1078,6 @@ QSlider::handle:hover {
|
|||
background-color: rgb(200, 199, 200);
|
||||
}
|
||||
|
||||
QSlider::sub-page {
|
||||
background-color: rgb(0, 188, 212); /* Cyan (Primary) */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::handle:disabled {
|
||||
background-color: rgb(122, 121, 122);
|
||||
}
|
||||
|
|
|
@ -615,63 +615,118 @@
|
|||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="VScrollArea" name="mixerScrollArea">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>220</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="volumeWidgets">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>230</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
<widget class="QStackedWidget" name="stackedMixerArea">
|
||||
<widget class="VScrollArea" name="hMixerScrollArea">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>175</width>
|
||||
<height>220</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_18">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="hVolumeWidgets">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>230</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
<layout class="QVBoxLayout" name="hVolControlLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="HScrollArea" name="vMixerScrollArea">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="vVolumeWidgets">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>16</width>
|
||||
<height>230</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
<layout class="QHBoxLayout" name="vVolControlLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -1614,6 +1669,12 @@
|
|||
<extends>QStatusBar</extends>
|
||||
<header>window-basic-status-bar.hpp</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>HScrollArea</class>
|
||||
<extends>QScrollArea</extends>
|
||||
<header>horizontal-scroll-area.hpp</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>VScrollArea</class>
|
||||
<extends>QScrollArea</extends>
|
||||
|
|
|
@ -25,6 +25,7 @@ set(frontend-tools_HEADERS
|
|||
tool-helpers.hpp
|
||||
../../properties-view.hpp
|
||||
../../properties-view.moc.hpp
|
||||
../../horizontal-scroll-area.hpp
|
||||
../../vertical-scroll-area.hpp
|
||||
../../double-slider.hpp
|
||||
)
|
||||
|
@ -34,6 +35,7 @@ set(frontend-tools_SOURCES
|
|||
frontend-tools.c
|
||||
output-timer.cpp
|
||||
../../properties-view.cpp
|
||||
../../horizontal-scroll-area.cpp
|
||||
../../vertical-scroll-area.cpp
|
||||
../../double-slider.cpp
|
||||
)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#include <QResizeEvent>
|
||||
#include "horizontal-scroll-area.hpp"
|
||||
|
||||
void HScrollArea::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
if (!!widget())
|
||||
widget()->setMaximumHeight(event->size().height());
|
||||
|
||||
QScrollArea::resizeEvent(event);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <QScrollArea>
|
||||
|
||||
class QResizeEvent;
|
||||
|
||||
class HScrollArea : public QScrollArea {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
inline HScrollArea(QWidget *parent = nullptr)
|
||||
: QScrollArea(parent)
|
||||
{
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
};
|
|
@ -418,6 +418,9 @@ bool OBSApp::InitGlobalConfigDefaults()
|
|||
"CurrentTheme", "Dark");
|
||||
}
|
||||
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"VerticalVolControl", false);
|
||||
|
||||
#ifdef _WIN32
|
||||
config_set_default_bool(globalConfig, "Audio", "DisableAudioDucking",
|
||||
true);
|
||||
|
|
|
@ -111,57 +111,20 @@ void VolControl::setPeakMeterType(enum obs_peak_meter_type peakMeterType)
|
|||
volMeter->setPeakMeterType(peakMeterType);
|
||||
}
|
||||
|
||||
VolControl::VolControl(OBSSource source_, bool showConfig)
|
||||
VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
|
||||
: source (std::move(source_)),
|
||||
levelTotal (0.0f),
|
||||
levelCount (0.0f),
|
||||
obs_fader (obs_fader_create(OBS_FADER_CUBIC)),
|
||||
obs_volmeter (obs_volmeter_create(OBS_FADER_LOG))
|
||||
obs_volmeter (obs_volmeter_create(OBS_FADER_LOG)),
|
||||
vertical (vertical)
|
||||
{
|
||||
QHBoxLayout *volLayout = new QHBoxLayout();
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout();
|
||||
QHBoxLayout *textLayout = new QHBoxLayout();
|
||||
QHBoxLayout *botLayout = new QHBoxLayout();
|
||||
|
||||
nameLabel = new QLabel();
|
||||
volLabel = new QLabel();
|
||||
volMeter = new VolumeMeter(nullptr, obs_volmeter);
|
||||
mute = new MuteCheckBox();
|
||||
slider = new QSlider(Qt::Horizontal);
|
||||
|
||||
QFont font = nameLabel->font();
|
||||
font.setPointSize(font.pointSize()-1);
|
||||
|
||||
QString sourceName = obs_source_get_name(source);
|
||||
setObjectName(sourceName);
|
||||
|
||||
nameLabel->setText(sourceName);
|
||||
nameLabel->setFont(font);
|
||||
volLabel->setFont(font);
|
||||
slider->setMinimum(0);
|
||||
slider->setMaximum(100);
|
||||
|
||||
// slider->setMaximumHeight(13);
|
||||
|
||||
textLayout->setContentsMargins(0, 0, 0, 0);
|
||||
textLayout->addWidget(nameLabel);
|
||||
textLayout->addWidget(volLabel);
|
||||
textLayout->setAlignment(nameLabel, Qt::AlignLeft);
|
||||
textLayout->setAlignment(volLabel, Qt::AlignRight);
|
||||
|
||||
bool muted = obs_source_muted(source);
|
||||
mute->setChecked(muted);
|
||||
mute->setAccessibleName(
|
||||
QTStr("VolControl.Mute").arg(sourceName));
|
||||
|
||||
volLayout->addWidget(slider);
|
||||
volLayout->addWidget(mute);
|
||||
volLayout->setSpacing(5);
|
||||
|
||||
botLayout->setContentsMargins(0, 0, 0, 0);
|
||||
botLayout->setSpacing(0);
|
||||
botLayout->addLayout(volLayout);
|
||||
|
||||
if (showConfig) {
|
||||
config = new QPushButton(this);
|
||||
config->setProperty("themeID", "configIconSmall");
|
||||
|
@ -176,18 +139,99 @@ VolControl::VolControl(OBSSource source_, bool showConfig)
|
|||
|
||||
connect(config, &QAbstractButton::clicked,
|
||||
this, &VolControl::EmitConfigClicked);
|
||||
|
||||
botLayout->addWidget(config);
|
||||
}
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->setContentsMargins(4, 4, 4, 4);
|
||||
mainLayout->setSpacing(2);
|
||||
mainLayout->addItem(textLayout);
|
||||
mainLayout->addWidget(volMeter);
|
||||
mainLayout->addItem(botLayout);
|
||||
|
||||
if (vertical) {
|
||||
QHBoxLayout *nameLayout = new QHBoxLayout;
|
||||
QHBoxLayout *controlLayout = new QHBoxLayout;
|
||||
QHBoxLayout *volLayout = new QHBoxLayout;
|
||||
QHBoxLayout *meterLayout = new QHBoxLayout;
|
||||
|
||||
volMeter = new VolumeMeter(nullptr, obs_volmeter, true);
|
||||
slider = new QSlider(Qt::Vertical);
|
||||
|
||||
nameLayout->setAlignment(Qt::AlignCenter);
|
||||
meterLayout->setAlignment(Qt::AlignCenter);
|
||||
controlLayout->setAlignment(Qt::AlignCenter);
|
||||
volLayout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
nameLayout->setContentsMargins(0, 0, 0, 0);
|
||||
nameLayout->setSpacing(0);
|
||||
nameLayout->addWidget(nameLabel);
|
||||
|
||||
controlLayout->setContentsMargins(0, 0, 0, 0);
|
||||
controlLayout->setSpacing(0);
|
||||
|
||||
if (showConfig)
|
||||
controlLayout->addWidget(config);
|
||||
|
||||
controlLayout->addItem(new QSpacerItem(3, 0));
|
||||
// Add Headphone (audio monitoring) widget here
|
||||
controlLayout->addWidget(mute);
|
||||
|
||||
meterLayout->setContentsMargins(0, 0, 0, 0);
|
||||
meterLayout->setSpacing(0);
|
||||
meterLayout->addWidget(volMeter);
|
||||
meterLayout->addWidget(slider);
|
||||
|
||||
volLayout->setContentsMargins(0, 0, 0, 0);
|
||||
volLayout->setSpacing(0);
|
||||
volLayout->addWidget(volLabel);
|
||||
|
||||
mainLayout->addItem(nameLayout);
|
||||
mainLayout->addItem(volLayout);
|
||||
mainLayout->addItem(meterLayout);
|
||||
mainLayout->addItem(controlLayout);
|
||||
|
||||
setMaximumWidth(110);
|
||||
} else {
|
||||
QHBoxLayout *volLayout = new QHBoxLayout;
|
||||
QHBoxLayout *textLayout = new QHBoxLayout;
|
||||
QHBoxLayout *botLayout = new QHBoxLayout;
|
||||
|
||||
volMeter = new VolumeMeter(nullptr, obs_volmeter, false);
|
||||
slider = new QSlider(Qt::Horizontal);
|
||||
|
||||
textLayout->setContentsMargins(0, 0, 0, 0);
|
||||
textLayout->addWidget(nameLabel);
|
||||
textLayout->addWidget(volLabel);
|
||||
textLayout->setAlignment(nameLabel, Qt::AlignLeft);
|
||||
textLayout->setAlignment(volLabel, Qt::AlignRight);
|
||||
|
||||
volLayout->addWidget(slider);
|
||||
volLayout->addWidget(mute);
|
||||
volLayout->setSpacing(5);
|
||||
|
||||
botLayout->setContentsMargins(0, 0, 0, 0);
|
||||
botLayout->setSpacing(0);
|
||||
botLayout->addLayout(volLayout);
|
||||
|
||||
if (showConfig)
|
||||
botLayout->addWidget(config);
|
||||
|
||||
mainLayout->addItem(textLayout);
|
||||
mainLayout->addWidget(volMeter);
|
||||
mainLayout->addItem(botLayout);
|
||||
}
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
QFont font = nameLabel->font();
|
||||
font.setPointSize(font.pointSize()-1);
|
||||
|
||||
nameLabel->setText(sourceName);
|
||||
nameLabel->setFont(font);
|
||||
volLabel->setFont(font);
|
||||
slider->setMinimum(0);
|
||||
slider->setMaximum(100);
|
||||
|
||||
bool muted = obs_source_muted(source);
|
||||
mute->setChecked(muted);
|
||||
mute->setAccessibleName(QTStr("VolControl.Mute").arg(sourceName));
|
||||
obs_fader_add_callback(obs_fader, OBSVolumeChanged, this);
|
||||
obs_volmeter_add_callback(obs_volmeter, OBSVolumeLevel, this);
|
||||
|
||||
|
@ -443,8 +487,10 @@ void VolumeMeter::setPeakMeterType(enum obs_peak_meter_type peakMeterType)
|
|||
}
|
||||
}
|
||||
|
||||
VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter)
|
||||
: QWidget(parent), obs_volmeter(obs_volmeter)
|
||||
VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter,
|
||||
bool vertical)
|
||||
: QWidget(parent), obs_volmeter(obs_volmeter),
|
||||
vertical(vertical)
|
||||
{
|
||||
// Use a font that can be rendered small.
|
||||
tickFont = QFont("Arial");
|
||||
|
@ -532,9 +578,12 @@ inline void VolumeMeter::handleChannelCofigurationChange()
|
|||
if (displayNrAudioChannels != currentNrAudioChannels) {
|
||||
displayNrAudioChannels = currentNrAudioChannels;
|
||||
|
||||
// Make room for 3 pixels high meter, with one pixel between
|
||||
// each. Then 9 pixels below it for ticks and numbers.
|
||||
setMinimumSize(130, displayNrAudioChannels * 4 + 8);
|
||||
// Make room for 3 pixels meter, with one pixel between each.
|
||||
// Then 9/13 pixels for ticks and numbers.
|
||||
if (vertical)
|
||||
setMinimumSize(displayNrAudioChannels * 4 + 14, 130);
|
||||
else
|
||||
setMinimumSize(130, displayNrAudioChannels * 4 + 8);
|
||||
|
||||
resetLevels();
|
||||
}
|
||||
|
@ -650,7 +699,7 @@ void VolumeMeter::paintInputMeter(QPainter &painter, int x, int y, int width,
|
|||
painter.fillRect(x, y, width, height, color);
|
||||
}
|
||||
|
||||
void VolumeMeter::paintTicks(QPainter &painter, int x, int y, int width,
|
||||
void VolumeMeter::paintHTicks(QPainter &painter, int x, int y, int width,
|
||||
int height)
|
||||
{
|
||||
qreal scale = width / minimumLevel;
|
||||
|
@ -679,6 +728,36 @@ void VolumeMeter::paintTicks(QPainter &painter, int x, int y, int width,
|
|||
}
|
||||
}
|
||||
|
||||
void VolumeMeter::paintVTicks(QPainter &painter, int x, int y, int height)
|
||||
{
|
||||
qreal scale = height / minimumLevel;
|
||||
|
||||
painter.setFont(tickFont);
|
||||
painter.setPen(majorTickColor);
|
||||
|
||||
// Draw major tick lines and numeric indicators.
|
||||
for (int i = 0; i >= minimumLevel; i-= 5) {
|
||||
int position = y + int((i * scale) - 1);
|
||||
QString str = QString::number(i);
|
||||
|
||||
if (i == 0)
|
||||
painter.drawText(x + 5, position + 4, str);
|
||||
else if (i == -60)
|
||||
painter.drawText(x + 4, position, str);
|
||||
else
|
||||
painter.drawText(x + 4, position + 2, str);
|
||||
painter.drawLine(x, position, x + 2, position);
|
||||
}
|
||||
|
||||
// Draw minor tick lines.
|
||||
painter.setPen(minorTickColor);
|
||||
for (int i = 0; i >= minimumLevel; i--) {
|
||||
int position = y + int((i * scale) - 1);
|
||||
if (i % 5 != 0)
|
||||
painter.drawLine(x, position, x + 1, position);
|
||||
}
|
||||
}
|
||||
|
||||
#define CLIP_FLASH_DURATION_MS 1000
|
||||
|
||||
void VolumeMeter::ClipEnding()
|
||||
|
@ -686,7 +765,7 @@ void VolumeMeter::ClipEnding()
|
|||
clipping = false;
|
||||
}
|
||||
|
||||
void VolumeMeter::paintMeter(QPainter &painter, int x, int y, int width,
|
||||
void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
|
||||
int height, float magnitude, float peak, float peakHold)
|
||||
{
|
||||
qreal scale = width / minimumLevel;
|
||||
|
@ -775,22 +854,111 @@ void VolumeMeter::paintMeter(QPainter &painter, int x, int y, int width,
|
|||
magnitudeColor);
|
||||
}
|
||||
|
||||
void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,
|
||||
int height, float magnitude, float peak, float peakHold)
|
||||
{
|
||||
qreal scale = height / minimumLevel;
|
||||
|
||||
QMutexLocker locker(&dataMutex);
|
||||
int minimumPosition = y + 0;
|
||||
int maximumPosition = y + height;
|
||||
int magnitudePosition = int(y + height - (magnitude * scale));
|
||||
int peakPosition = int(y + height - (peak * scale));
|
||||
int peakHoldPosition = int(y + height - (peakHold * scale));
|
||||
int warningPosition = int(y + height - (warningLevel * scale));
|
||||
int errorPosition = int(y + height - (errorLevel * scale));
|
||||
|
||||
int nominalLength = warningPosition - minimumPosition;
|
||||
int warningLength = errorPosition - warningPosition;
|
||||
int errorLength = maximumPosition - errorPosition;
|
||||
locker.unlock();
|
||||
|
||||
if (clipping) {
|
||||
peakPosition = maximumPosition;
|
||||
}
|
||||
|
||||
if (peakPosition < minimumPosition) {
|
||||
painter.fillRect(x, minimumPosition, width, nominalLength,
|
||||
backgroundNominalColor);
|
||||
painter.fillRect(x, warningPosition, width, warningLength,
|
||||
backgroundWarningColor);
|
||||
painter.fillRect(x, errorPosition, width, errorLength,
|
||||
backgroundErrorColor);
|
||||
} else if (peakPosition < warningPosition) {
|
||||
painter.fillRect(x, minimumPosition, width, peakPosition -
|
||||
minimumPosition, foregroundNominalColor);
|
||||
painter.fillRect(x, peakPosition, width, warningPosition -
|
||||
peakPosition, backgroundNominalColor);
|
||||
painter.fillRect(x, warningPosition, width, warningLength,
|
||||
backgroundWarningColor);
|
||||
painter.fillRect(x, errorPosition, width, errorLength,
|
||||
backgroundErrorColor);
|
||||
} else if (peakPosition < errorPosition) {
|
||||
painter.fillRect(x,minimumPosition, width, nominalLength,
|
||||
foregroundNominalColor);
|
||||
painter.fillRect(x, warningPosition, width, peakPosition -
|
||||
warningPosition, foregroundWarningColor);
|
||||
painter.fillRect(x, peakPosition, width, errorPosition -
|
||||
peakPosition, backgroundWarningColor);
|
||||
painter.fillRect(x, errorPosition, width, errorLength,
|
||||
backgroundErrorColor);
|
||||
} else if (peakPosition < maximumPosition) {
|
||||
painter.fillRect(x, minimumPosition, width, nominalLength,
|
||||
foregroundNominalColor);
|
||||
painter.fillRect(x, warningPosition, width, warningLength,
|
||||
foregroundWarningColor);
|
||||
painter.fillRect(x, errorPosition, width, peakPosition -
|
||||
errorPosition, foregroundErrorColor);
|
||||
painter.fillRect(x, peakPosition, width, maximumPosition -
|
||||
peakPosition, backgroundErrorColor);
|
||||
} else {
|
||||
if (!clipping) {
|
||||
QTimer::singleShot(CLIP_FLASH_DURATION_MS, this,
|
||||
SLOT(ClipEnding()));
|
||||
clipping = true;
|
||||
}
|
||||
|
||||
int end = errorLength + warningLength + nominalLength;
|
||||
painter.fillRect(x, minimumPosition, width, end,
|
||||
QBrush(foregroundErrorColor));
|
||||
}
|
||||
|
||||
if (peakHoldPosition - 3 < minimumPosition)
|
||||
;// Peak-hold below minimum, no drawing.
|
||||
else if (peakHoldPosition < warningPosition)
|
||||
painter.fillRect(x, peakHoldPosition - 3, width, 3,
|
||||
foregroundNominalColor);
|
||||
else if (peakHoldPosition < errorPosition)
|
||||
painter.fillRect(x, peakHoldPosition - 3, width, 3,
|
||||
foregroundWarningColor);
|
||||
else
|
||||
painter.fillRect(x, peakHoldPosition - 3, width, 3,
|
||||
foregroundErrorColor);
|
||||
|
||||
if (magnitudePosition - 3 >= minimumPosition)
|
||||
painter.fillRect(x, magnitudePosition - 3, width, 3,
|
||||
magnitudeColor);
|
||||
}
|
||||
|
||||
void VolumeMeter::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
UNUSED_PARAMETER(event);
|
||||
|
||||
uint64_t ts = os_gettime_ns();
|
||||
qreal timeSinceLastRedraw = (ts - lastRedrawTime) * 0.000000001;
|
||||
|
||||
int width = size().width();
|
||||
int height = size().height();
|
||||
const QRect rect = event->region().boundingRect();
|
||||
int width = rect.width();
|
||||
int height = rect.height();
|
||||
|
||||
handleChannelCofigurationChange();
|
||||
calculateBallistics(ts, timeSinceLastRedraw);
|
||||
bool idle = detectIdle(ts);
|
||||
|
||||
// Draw the ticks in a off-screen buffer when the widget changes size.
|
||||
QSize tickPaintCacheSize = QSize(width, 9);
|
||||
QSize tickPaintCacheSize;
|
||||
if (vertical)
|
||||
tickPaintCacheSize = QSize(14, height);
|
||||
else
|
||||
tickPaintCacheSize = QSize(width, 9);
|
||||
if (tickPaintCache == nullptr ||
|
||||
tickPaintCache->size() != tickPaintCacheSize) {
|
||||
delete tickPaintCache;
|
||||
|
@ -800,29 +968,56 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
|
|||
tickPaintCache->fill(clearColor);
|
||||
|
||||
QPainter tickPainter(tickPaintCache);
|
||||
paintTicks(tickPainter, 6, 0, tickPaintCacheSize.width() - 6,
|
||||
tickPaintCacheSize.height());
|
||||
if (vertical) {
|
||||
tickPainter.translate(0, height);
|
||||
tickPainter.scale(1, -1);
|
||||
paintVTicks(tickPainter, 0, 11,
|
||||
tickPaintCacheSize.height() - 11);
|
||||
} else {
|
||||
paintHTicks(tickPainter, 6, 0,
|
||||
tickPaintCacheSize.width() - 6,
|
||||
tickPaintCacheSize.height());
|
||||
}
|
||||
tickPainter.end();
|
||||
}
|
||||
|
||||
// Actual painting of the widget starts here.
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(0, height - 9, *tickPaintCache);
|
||||
if (vertical) {
|
||||
// Invert the Y axis to ease the math
|
||||
painter.translate(0, height);
|
||||
painter.scale(1, -1);
|
||||
painter.drawPixmap(displayNrAudioChannels * 4 - 1, 7,
|
||||
*tickPaintCache);
|
||||
} else {
|
||||
painter.drawPixmap(0, height - 9, *tickPaintCache);
|
||||
}
|
||||
|
||||
for (int channelNr = 0; channelNr < displayNrAudioChannels;
|
||||
channelNr++) {
|
||||
paintMeter(painter, 5, channelNr * 4, width - 5, 3,
|
||||
displayMagnitude[channelNr],
|
||||
displayPeak[channelNr],
|
||||
displayPeakHold[channelNr]);
|
||||
if (vertical)
|
||||
paintVMeter(painter, channelNr * 4, 8, 3, height - 10,
|
||||
displayMagnitude[channelNr],
|
||||
displayPeak[channelNr],
|
||||
displayPeakHold[channelNr]);
|
||||
else
|
||||
paintHMeter(painter, 5, channelNr * 4, width - 5, 3,
|
||||
displayMagnitude[channelNr],
|
||||
displayPeak[channelNr],
|
||||
displayPeakHold[channelNr]);
|
||||
|
||||
if (!idle) {
|
||||
// By not drawing the input meter boxes the user can
|
||||
// see that the audio stream has been stopped, without
|
||||
// having too much visual impact.
|
||||
if (idle)
|
||||
continue;
|
||||
|
||||
// By not drawing the input meter boxes the user can
|
||||
// see that the audio stream has been stopped, without
|
||||
// having too much visual impact.
|
||||
if (vertical)
|
||||
paintInputMeter(painter, channelNr * 4, 3, 3, 3,
|
||||
displayInputPeakHold[channelNr]);
|
||||
else
|
||||
paintInputMeter(painter, 0, channelNr * 4, 3, 3,
|
||||
displayInputPeakHold[channelNr]);
|
||||
}
|
||||
}
|
||||
|
||||
lastRedrawTime = ts;
|
||||
|
|
|
@ -96,12 +96,15 @@ private:
|
|||
inline void calculateBallisticsForChannel(int channelNr,
|
||||
uint64_t ts, qreal timeSinceLastRedraw);
|
||||
|
||||
void paintInputMeter(QPainter &painter, int x, int y,
|
||||
int width, int height, float peakHold);
|
||||
void paintMeter(QPainter &painter, int x, int y,
|
||||
int width, int height,
|
||||
float magnitude, float peak, float peakHold);
|
||||
void paintTicks(QPainter &painter, int x, int y, int width, int height);
|
||||
void paintInputMeter(QPainter &painter, int x, int y, int width,
|
||||
int height, float peakHold);
|
||||
void paintHMeter(QPainter &painter, int x, int y, int width, int height,
|
||||
float magnitude, float peak, float peakHold);
|
||||
void paintHTicks(QPainter &painter, int x, int y, int width,
|
||||
int height);
|
||||
void paintVMeter(QPainter &painter, int x, int y, int width, int height,
|
||||
float magnitude, float peak, float peakHold);
|
||||
void paintVTicks(QPainter &painter, int x, int y, int height);
|
||||
|
||||
QMutex dataMutex;
|
||||
|
||||
|
@ -142,10 +145,12 @@ private:
|
|||
|
||||
uint64_t lastRedrawTime = 0;
|
||||
bool clipping = false;
|
||||
bool vertical;
|
||||
|
||||
public:
|
||||
explicit VolumeMeter(QWidget *parent = nullptr,
|
||||
obs_volmeter_t *obs_volmeter = nullptr);
|
||||
obs_volmeter_t *obs_volmeter = nullptr,
|
||||
bool vertical = false);
|
||||
~VolumeMeter();
|
||||
|
||||
void setLevels(
|
||||
|
@ -230,6 +235,7 @@ private:
|
|||
float levelCount;
|
||||
obs_fader_t *obs_fader;
|
||||
obs_volmeter_t *obs_volmeter;
|
||||
bool vertical;
|
||||
|
||||
static void OBSVolumeChanged(void *param, float db);
|
||||
static void OBSVolumeLevel(void *data,
|
||||
|
@ -252,7 +258,8 @@ signals:
|
|||
void ConfigClicked();
|
||||
|
||||
public:
|
||||
explicit VolControl(OBSSource source, bool showConfig = false);
|
||||
explicit VolControl(OBSSource source, bool showConfig = false,
|
||||
bool vertical = false);
|
||||
~VolControl();
|
||||
|
||||
inline obs_source_t *GetSource() const {return source;}
|
||||
|
|
|
@ -1572,6 +1572,10 @@ void OBSBasic::OBSInit()
|
|||
}
|
||||
}
|
||||
|
||||
bool vertical = config_get_bool(App()->GlobalConfig(), "BasicWindow",
|
||||
"VerticalVolControl");
|
||||
ui->stackedMixerArea->setCurrentIndex(vertical);
|
||||
|
||||
if (config_get_bool(basicConfig, "General", "OpenStatsOnStartup"))
|
||||
on_stats_triggered();
|
||||
|
||||
|
@ -2471,6 +2475,11 @@ void OBSBasic::VolControlContextMenu()
|
|||
QAction propertiesAction(QTStr("Properties"), this);
|
||||
QAction advPropAction(QTStr("Basic.MainMenu.Edit.AdvAudio"), this);
|
||||
|
||||
QAction toggleControlLayoutAction(QTStr("VerticalLayout"), this);
|
||||
toggleControlLayoutAction.setCheckable(true);
|
||||
toggleControlLayoutAction.setChecked(config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "VerticalVolControl"));
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
connect(&hideAction, &QAction::triggered,
|
||||
|
@ -2495,6 +2504,12 @@ void OBSBasic::VolControlContextMenu()
|
|||
|
||||
/* ------------------- */
|
||||
|
||||
connect(&toggleControlLayoutAction, &QAction::changed, this,
|
||||
&OBSBasic::ToggleVolControlLayout,
|
||||
Qt::DirectConnection);
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
hideAction.setProperty("volControl",
|
||||
QVariant::fromValue<VolControl*>(vol));
|
||||
mixerRenameAction.setProperty("volControl",
|
||||
|
@ -2512,18 +2527,35 @@ void OBSBasic::VolControlContextMenu()
|
|||
popup.addAction(&hideAction);
|
||||
popup.addAction(&mixerRenameAction);
|
||||
popup.addSeparator();
|
||||
popup.addAction(&toggleControlLayoutAction);
|
||||
popup.addSeparator();
|
||||
popup.addAction(&filtersAction);
|
||||
popup.addAction(&propertiesAction);
|
||||
popup.addAction(&advPropAction);
|
||||
popup.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void OBSBasic::on_mixerScrollArea_customContextMenuRequested()
|
||||
void OBSBasic::on_hMixerScrollArea_customContextMenuRequested()
|
||||
{
|
||||
StackedMixerAreaContextMenuRequested();
|
||||
}
|
||||
|
||||
void OBSBasic::on_vMixerScrollArea_customContextMenuRequested()
|
||||
{
|
||||
StackedMixerAreaContextMenuRequested();
|
||||
}
|
||||
|
||||
void OBSBasic::StackedMixerAreaContextMenuRequested()
|
||||
{
|
||||
QAction unhideAllAction(QTStr("UnhideAll"), this);
|
||||
|
||||
QAction advPropAction(QTStr("Basic.MainMenu.Edit.AdvAudio"), this);
|
||||
|
||||
QAction toggleControlLayoutAction(QTStr("VerticalLayout"), this);
|
||||
toggleControlLayoutAction.setCheckable(true);
|
||||
toggleControlLayoutAction.setChecked(config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "VerticalVolControl"));
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
connect(&unhideAllAction, &QAction::triggered,
|
||||
|
@ -2536,19 +2568,49 @@ void OBSBasic::on_mixerScrollArea_customContextMenuRequested()
|
|||
|
||||
/* ------------------- */
|
||||
|
||||
connect(&toggleControlLayoutAction, &QAction::changed, this,
|
||||
&OBSBasic::ToggleVolControlLayout,
|
||||
Qt::DirectConnection);
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
QMenu popup(this);
|
||||
popup.addAction(&unhideAllAction);
|
||||
popup.addSeparator();
|
||||
popup.addAction(&toggleControlLayoutAction);
|
||||
popup.addSeparator();
|
||||
popup.addAction(&advPropAction);
|
||||
popup.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void OBSBasic::ToggleVolControlLayout()
|
||||
{
|
||||
bool vertical = !config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"VerticalVolControl");
|
||||
config_set_bool(GetGlobalConfig(), "BasicWindow", "VerticalVolControl",
|
||||
vertical);
|
||||
ui->stackedMixerArea->setCurrentIndex(vertical);
|
||||
|
||||
// We need to store it so we can delete current and then add
|
||||
// at the right order
|
||||
vector<OBSSource> sources;
|
||||
for (size_t i = 0; i != volumes.size(); i++)
|
||||
sources.emplace_back(volumes[i]->GetSource());
|
||||
|
||||
ClearVolumeControls();
|
||||
|
||||
for (const auto &source : sources)
|
||||
ActivateAudioSource(source);
|
||||
}
|
||||
|
||||
void OBSBasic::ActivateAudioSource(OBSSource source)
|
||||
{
|
||||
if (SourceMixerHidden(source))
|
||||
return;
|
||||
|
||||
VolControl *vol = new VolControl(source, true);
|
||||
bool vertical = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"VerticalVolControl");
|
||||
VolControl *vol = new VolControl(source, true, vertical);
|
||||
|
||||
double meterDecayRate = config_get_double(basicConfig, "Audio",
|
||||
"MeterDecayRate");
|
||||
|
@ -2582,7 +2644,10 @@ void OBSBasic::ActivateAudioSource(OBSSource source)
|
|||
InsertQObjectByName(volumes, vol);
|
||||
|
||||
for (auto volume : volumes) {
|
||||
ui->volumeWidgets->layout()->addWidget(volume);
|
||||
if (vertical)
|
||||
ui->vVolControlLayout->addWidget(volume);
|
||||
else
|
||||
ui->hVolControlLayout->addWidget(volume);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -258,6 +258,7 @@ private:
|
|||
void GetAudioSourceFilters();
|
||||
void GetAudioSourceProperties();
|
||||
void VolControlContextMenu();
|
||||
void ToggleVolControlLayout();
|
||||
|
||||
void RefreshSceneCollections();
|
||||
void ChangeSceneCollection();
|
||||
|
@ -455,7 +456,8 @@ private slots:
|
|||
|
||||
void MixerRenameSource();
|
||||
|
||||
void on_mixerScrollArea_customContextMenuRequested();
|
||||
void on_vMixerScrollArea_customContextMenuRequested();
|
||||
void on_hMixerScrollArea_customContextMenuRequested();
|
||||
|
||||
void on_actionCopySource_triggered();
|
||||
void on_actionPasteRef_triggered();
|
||||
|
@ -715,6 +717,8 @@ private slots:
|
|||
|
||||
void DeferredLoad(const QString &file, int requeueCount);
|
||||
|
||||
void StackedMixerAreaContextMenuRequested();
|
||||
|
||||
public slots:
|
||||
void on_actionResetTransform_triggered();
|
||||
|
||||
|
|
Loading…
Reference in New Issue