mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-05-12 01:06:46 -04:00
frontend: Optimize audio mixer updates
This commit is contained in:
@@ -165,6 +165,36 @@ VolumeControl::~VolumeControl()
|
||||
}
|
||||
}
|
||||
|
||||
const QIcon &VolumeControl::getUnassignedIcon()
|
||||
{
|
||||
static const QIcon &icon = *new QIcon(":/res/images/unassigned.svg");
|
||||
return icon;
|
||||
}
|
||||
|
||||
const QIcon &VolumeControl::getMutedIcon()
|
||||
{
|
||||
static const QIcon &icon = *new QIcon(":/settings/images/settings/audio.svg");
|
||||
return icon;
|
||||
}
|
||||
|
||||
const QIcon &VolumeControl::getUnmutedIcon()
|
||||
{
|
||||
static const QIcon &icon = *new QIcon(":/settings/images/settings/audio.svg");
|
||||
return icon;
|
||||
}
|
||||
|
||||
const QIcon &VolumeControl::getMonitorOnIcon()
|
||||
{
|
||||
static const QIcon &icon = *new QIcon(":/res/images/headphones.svg");
|
||||
return icon;
|
||||
}
|
||||
|
||||
const QIcon &VolumeControl::getMonitorOffIcon()
|
||||
{
|
||||
static const QIcon &icon = *new QIcon(":/res/images/headphones-off.svg");
|
||||
return icon;
|
||||
}
|
||||
|
||||
void VolumeControl::obsVolumeChanged(void *data, float)
|
||||
{
|
||||
VolumeControl *volControl = static_cast<VolumeControl *>(data);
|
||||
@@ -600,7 +630,8 @@ void VolumeControl::updateCategoryLabel()
|
||||
categoryLabel->setText(labelText);
|
||||
categoryLabel->setAlignment(Qt::AlignCenter);
|
||||
|
||||
utils->polishChildren();
|
||||
style()->polish(categoryLabel);
|
||||
style()->polish(volumeMeter);
|
||||
|
||||
bool forceUpdate = true;
|
||||
volumeMeter->updateBackgroundCache(forceUpdate);
|
||||
@@ -727,13 +758,6 @@ void VolumeControl::updateMixerState()
|
||||
volumeMeter->setMuted((showAsMuted || showAsUnassigned) && !showAsMonitored);
|
||||
setUseDisabledColors(showAsMuted || !isActive);
|
||||
|
||||
// Qt doesn't support overriding the QPushButton icon using pseudo state selectors like :checked
|
||||
// in QSS so we set a checked class selector on the button to be used instead.
|
||||
utils->toggleClass(muteButton, "checked", showAsMuted);
|
||||
utils->toggleClass(monitorButton, "checked", showAsMonitored);
|
||||
|
||||
utils->toggleClass(muteButton, "mute-unassigned", showAsUnassigned);
|
||||
|
||||
muteButton->setChecked(showAsMuted);
|
||||
monitorButton->setChecked(showAsMonitored);
|
||||
|
||||
@@ -745,36 +769,28 @@ void VolumeControl::updateMixerState()
|
||||
monitorButton->setToolTip(monitorTooltip);
|
||||
|
||||
if (showAsUnassigned) {
|
||||
QIcon unassignedIcon;
|
||||
unassignedIcon.addFile(QString::fromUtf8(":/res/images/unassigned.svg"), QSize(16, 16),
|
||||
QIcon::Mode::Normal, QIcon::State::Off);
|
||||
muteButton->setIcon(unassignedIcon);
|
||||
muteButton->setIcon(getUnassignedIcon());
|
||||
} else if (showAsMuted) {
|
||||
QIcon mutedIcon;
|
||||
mutedIcon.addFile(QString::fromUtf8(":/res/images/mute.svg"), QSize(16, 16), QIcon::Mode::Normal,
|
||||
QIcon::State::Off);
|
||||
muteButton->setIcon(mutedIcon);
|
||||
muteButton->setIcon(getMutedIcon());
|
||||
} else {
|
||||
QIcon unmutedIcon;
|
||||
unmutedIcon.addFile(QString::fromUtf8(":/settings/images/settings/audio.svg"), QSize(16, 16),
|
||||
QIcon::Mode::Normal, QIcon::State::Off);
|
||||
muteButton->setIcon(unmutedIcon);
|
||||
muteButton->setIcon(getUnmutedIcon());
|
||||
}
|
||||
|
||||
if (showAsMonitored) {
|
||||
QIcon monitorOnIcon;
|
||||
monitorOnIcon.addFile(QString::fromUtf8(":/res/images/headphones.svg"), QSize(16, 16),
|
||||
QIcon::Mode::Normal, QIcon::State::Off);
|
||||
monitorButton->setIcon(monitorOnIcon);
|
||||
monitorButton->setIcon(getMonitorOnIcon());
|
||||
} else {
|
||||
QIcon monitorOffIcon;
|
||||
monitorOffIcon.addFile(QString::fromUtf8(":/res/images/headphones-off.svg"), QSize(16, 16),
|
||||
QIcon::Mode::Normal, QIcon::State::Off);
|
||||
monitorButton->setIcon(monitorOffIcon);
|
||||
monitorButton->setIcon(getMonitorOffIcon());
|
||||
}
|
||||
|
||||
utils->repolish(muteButton);
|
||||
utils->repolish(monitorButton);
|
||||
// Qt doesn't support overriding the QPushButton icon using pseudo state selectors like :checked
|
||||
// in QSS so we set a checked class selector on the button to be used instead.
|
||||
utils->toggleClass(muteButton, "checked", showAsMuted);
|
||||
utils->toggleClass(monitorButton, "checked", showAsMonitored);
|
||||
|
||||
utils->toggleClass(muteButton, "mute-unassigned", showAsUnassigned);
|
||||
|
||||
style()->polish(muteButton);
|
||||
style()->polish(monitorButton);
|
||||
|
||||
updateCategoryLabel();
|
||||
}
|
||||
|
||||
@@ -90,6 +90,12 @@ private:
|
||||
|
||||
QMenu *contextMenu;
|
||||
|
||||
static const QIcon &getUnassignedIcon();
|
||||
static const QIcon &getMutedIcon();
|
||||
static const QIcon &getUnmutedIcon();
|
||||
static const QIcon &getMonitorOnIcon();
|
||||
static const QIcon &getMonitorOffIcon();
|
||||
|
||||
static void obsVolumeChanged(void *param, float db);
|
||||
static void obsVolumeMuted(void *data, calldata_t *calldata);
|
||||
static void obsMixersOrMonitoringChanged(void *data, calldata_t *);
|
||||
@@ -99,7 +105,6 @@ private:
|
||||
|
||||
void setLayoutVertical(bool vertical);
|
||||
void showVolumeControlMenu(QPoint pos = QPoint(0, 0));
|
||||
void updateCategoryLabel();
|
||||
void updateDecayRate();
|
||||
void updatePeakMeterType();
|
||||
|
||||
@@ -156,6 +161,7 @@ public:
|
||||
}
|
||||
|
||||
void updateName();
|
||||
void updateCategoryLabel();
|
||||
void refreshColors();
|
||||
void setLevels(const float magnitude[MAX_AUDIO_CHANNELS], const float peak[MAX_AUDIO_CHANNELS],
|
||||
const float inputPeak[MAX_AUDIO_CHANNELS]);
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
#include "moc_AudioMixer.cpp"
|
||||
|
||||
constexpr int GLOBAL_SOURCE_TOTAL = 6;
|
||||
constexpr int kGlobalSourceTotal = 6;
|
||||
|
||||
namespace {
|
||||
bool isHiddenInMixer(obs_source_t *source)
|
||||
@@ -371,6 +371,7 @@ void AudioMixer::updateControlVisibility(QString uuid)
|
||||
bool show = getMixerVisibilityForControl(control);
|
||||
|
||||
if (show) {
|
||||
control->updateMixerState();
|
||||
control->show();
|
||||
} else {
|
||||
control->hide();
|
||||
@@ -454,7 +455,7 @@ void AudioMixer::updateGlobalSources()
|
||||
{
|
||||
globalSources.clear();
|
||||
|
||||
for (int i = 1; i <= GLOBAL_SOURCE_TOTAL; i++) {
|
||||
for (int i = 1; i <= kGlobalSourceTotal; i++) {
|
||||
OBSSourceAutoRelease source = obs_get_output_source(i);
|
||||
if (source) {
|
||||
auto uuidPointer = obs_source_get_uuid(source);
|
||||
@@ -708,7 +709,7 @@ void AudioMixer::updateVolumeLayouts()
|
||||
layout->insertWidget(index, volControl);
|
||||
volControl->setVertical(vertical);
|
||||
volControl->updateName();
|
||||
volControl->updateMixerState();
|
||||
volControl->updateCategoryLabel();
|
||||
|
||||
bool showControl = getMixerVisibilityForControl(volControl);
|
||||
|
||||
@@ -1015,9 +1016,11 @@ void AudioMixer::obsSourceActivated(void *data, calldata_t *params)
|
||||
uint32_t flags = obs_source_get_output_flags(source);
|
||||
|
||||
if (flags & OBS_SOURCE_AUDIO) {
|
||||
auto mixer = static_cast<AudioMixer *>(data);
|
||||
auto uuidPointer = obs_source_get_uuid(source);
|
||||
QMetaObject::invokeMethod(static_cast<AudioMixer *>(data), "updateControlVisibility",
|
||||
Qt::QueuedConnection, Q_ARG(QString, QString::fromUtf8(uuidPointer)));
|
||||
|
||||
QMetaObject::invokeMethod(mixer, "updateControlVisibility", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromUtf8(uuidPointer)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1027,9 +1030,11 @@ void AudioMixer::obsSourceDeactivated(void *data, calldata_t *params)
|
||||
uint32_t flags = obs_source_get_output_flags(source);
|
||||
|
||||
if (flags & OBS_SOURCE_AUDIO) {
|
||||
auto mixer = static_cast<AudioMixer *>(data);
|
||||
auto uuidPointer = obs_source_get_uuid(source);
|
||||
QMetaObject::invokeMethod(static_cast<AudioMixer *>(data), "updateControlVisibility",
|
||||
Qt::QueuedConnection, Q_ARG(QString, QString::fromUtf8(uuidPointer)));
|
||||
|
||||
QMetaObject::invokeMethod(mixer, "updateControlVisibility", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromUtf8(uuidPointer)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1040,8 +1045,10 @@ void AudioMixer::obsSourceAudioActivated(void *data, calldata_t *params)
|
||||
bool audioActive = obs_source_audio_active(source);
|
||||
|
||||
if (flags & OBS_SOURCE_AUDIO && audioActive) {
|
||||
auto mixer = static_cast<AudioMixer *>(data);
|
||||
auto uuidPointer = obs_source_get_uuid(source);
|
||||
QMetaObject::invokeMethod(static_cast<AudioMixer *>(data), "addSource", Qt::QueuedConnection,
|
||||
|
||||
QMetaObject::invokeMethod(mixer, "addSource", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromUtf8(uuidPointer)));
|
||||
}
|
||||
}
|
||||
@@ -1052,8 +1059,10 @@ void AudioMixer::obsSourceAudioDeactivated(void *data, calldata_t *params)
|
||||
uint32_t flags = obs_source_get_output_flags(source);
|
||||
|
||||
if (flags & OBS_SOURCE_AUDIO) {
|
||||
auto mixer = static_cast<AudioMixer *>(data);
|
||||
auto uuidPointer = obs_source_get_uuid(source);
|
||||
QMetaObject::invokeMethod(static_cast<AudioMixer *>(data), "removeSource", Qt::QueuedConnection,
|
||||
|
||||
QMetaObject::invokeMethod(mixer, "updateControlVisibility", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromUtf8(uuidPointer)));
|
||||
}
|
||||
}
|
||||
@@ -1065,8 +1074,10 @@ void AudioMixer::obsSourceCreate(void *data, calldata_t *params)
|
||||
bool audioActive = obs_source_audio_active(source);
|
||||
|
||||
if (flags & OBS_SOURCE_AUDIO && audioActive) {
|
||||
auto mixer = static_cast<AudioMixer *>(data);
|
||||
auto uuidPointer = obs_source_get_uuid(source);
|
||||
QMetaObject::invokeMethod(static_cast<AudioMixer *>(data), "addSource", Qt::QueuedConnection,
|
||||
|
||||
QMetaObject::invokeMethod(mixer, "addSource", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromUtf8(uuidPointer)));
|
||||
}
|
||||
}
|
||||
@@ -1077,15 +1088,19 @@ void AudioMixer::obsSourceRemove(void *data, calldata_t *params)
|
||||
uint32_t flags = obs_source_get_output_flags(source);
|
||||
|
||||
if (flags & OBS_SOURCE_AUDIO) {
|
||||
auto mixer = static_cast<AudioMixer *>(data);
|
||||
auto uuidPointer = obs_source_get_uuid(source);
|
||||
QMetaObject::invokeMethod(static_cast<AudioMixer *>(data), "removeSource", Qt::QueuedConnection,
|
||||
|
||||
QMetaObject::invokeMethod(mixer, "removeSource", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromUtf8(uuidPointer)));
|
||||
}
|
||||
}
|
||||
|
||||
void AudioMixer::obsSourceRename(void *data, calldata_t *)
|
||||
{
|
||||
QMetaObject::invokeMethod(static_cast<AudioMixer *>(data), "queueLayoutUpdate", Qt::QueuedConnection);
|
||||
auto mixer = static_cast<AudioMixer *>(data);
|
||||
|
||||
QMetaObject::invokeMethod(mixer, "queueLayoutUpdate", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void AudioMixer::obsSceneItemVisibleChange(void *data, calldata_t *params)
|
||||
|
||||
@@ -78,9 +78,7 @@ private:
|
||||
|
||||
bool showToolbar{true};
|
||||
|
||||
QFrame *mixerFrame{nullptr};
|
||||
QVBoxLayout *mainLayout{nullptr};
|
||||
QVBoxLayout *mixerLayout{nullptr};
|
||||
|
||||
QStackedWidget *stackedMixerArea{nullptr};
|
||||
QToolBar *mixerToolbar{nullptr};
|
||||
|
||||
@@ -48,11 +48,7 @@ public:
|
||||
}
|
||||
|
||||
void repolish() { repolish(parent); }
|
||||
static void repolish(QWidget *widget)
|
||||
{
|
||||
widget->style()->unpolish(widget);
|
||||
widget->style()->polish(widget);
|
||||
}
|
||||
static void repolish(QWidget *widget) { widget->style()->polish(widget); }
|
||||
|
||||
// Adds a style class to the widget
|
||||
void addClass(const QString &classname) { addClass(parent, classname); }
|
||||
|
||||
Reference in New Issue
Block a user