115 lines
4.7 KiB
C++
115 lines
4.7 KiB
C++
// Copyright 2022-2023 The Mumble Developers. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license
|
|
// that can be found in the LICENSE file at the root of the
|
|
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
|
|
|
|
#include "VolumeSliderWidgetAction.h"
|
|
|
|
#include "MumbleApplication.h"
|
|
#include "VolumeAdjustment.h"
|
|
#include "widgets/EventFilters.h"
|
|
|
|
#include <QHBoxLayout>
|
|
#include <QLabel>
|
|
#include <QSlider>
|
|
#include <QToolTip>
|
|
|
|
VolumeSliderWidgetAction::VolumeSliderWidgetAction(QWidget *parent)
|
|
: QWidgetAction(parent), m_widget(make_qt_unique< QWidget >(parent)),
|
|
m_volumeSlider(new QSlider(Qt::Horizontal, parent)), m_label(new QLabel("0 db", parent)) {
|
|
m_volumeSlider->setMinimum(-30);
|
|
m_volumeSlider->setMaximum(30);
|
|
m_volumeSlider->setAccessibleName(tr("Local volume adjustment"));
|
|
|
|
m_label->setStyleSheet("QLabel { margin-left: 0px; padding: 0px; }");
|
|
m_volumeSlider->setStyleSheet("QSlider { margin-right: 0px; }");
|
|
|
|
KeyEventObserver *keyEventFilter =
|
|
new KeyEventObserver(this, QEvent::KeyRelease, false, { Qt::Key_Left, Qt::Key_Right });
|
|
m_volumeSlider->installEventFilter(keyEventFilter);
|
|
|
|
// The list of wheel events observed seems odd at first. We have to check for multiple
|
|
// Qt::ScrollPhase types, because Qt has a weird/non-deterministic behavior regarding
|
|
// scroll phases. There seems to be at least 3 different states the application can
|
|
// be in at each start-up, which all produce different scroll phases using the same
|
|
// inputs. This might very well be a Qt bug that is fixed in future versions and this
|
|
// list could possibly be updated to reflect that. According to official Qt docs, observing
|
|
// Qt::ScrollUpdate should be enough. But as of Qt 5.15.8 it is not.
|
|
MouseWheelEventObserver *wheelEventFilter =
|
|
new MouseWheelEventObserver(this, { Qt::ScrollMomentum, Qt::ScrollUpdate, Qt::ScrollEnd }, false);
|
|
m_volumeSlider->installEventFilter(wheelEventFilter);
|
|
|
|
|
|
// Since we do not want the inline label to update when we drag the mouse, we
|
|
// must install a click event observer to update the label when the user just randomly
|
|
// clicks on the slider bar.
|
|
MouseClickEventObserver *mouseEventFilter = new MouseClickEventObserver(this, false);
|
|
m_volumeSlider->installEventFilter(mouseEventFilter);
|
|
connect(mouseEventFilter, &MouseClickEventObserver::clickEventObserved, this, [=]() {
|
|
m_volumeSlider->setFocus(Qt::TabFocusReason);
|
|
updateLabelValue(false);
|
|
});
|
|
|
|
// Also update the label explicitly when the slider body is released.
|
|
connect(m_volumeSlider, &QSlider::sliderReleased, this, [=]() {
|
|
m_volumeSlider->setFocus(Qt::TabFocusReason);
|
|
updateLabelValue(false);
|
|
});
|
|
|
|
connect(m_volumeSlider, &QSlider::valueChanged, this, &VolumeSliderWidgetAction::on_VolumeSlider_valueChanged);
|
|
|
|
connect(m_volumeSlider, &QSlider::sliderReleased, this, &VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted);
|
|
connect(keyEventFilter, &KeyEventObserver::keyEventObserved, this,
|
|
&VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted);
|
|
connect(wheelEventFilter, &MouseWheelEventObserver::wheelEventObserved, this,
|
|
&VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted);
|
|
|
|
UpDownKeyEventFilter *eventFilter = new UpDownKeyEventFilter(this);
|
|
m_volumeSlider->installEventFilter(eventFilter);
|
|
|
|
// Used to display the drag tooltip at the mouse position
|
|
m_volumeSlider->setProperty("mouseTracking", true);
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout();
|
|
layout->addWidget(m_volumeSlider);
|
|
layout->addWidget(m_label);
|
|
layout->setContentsMargins(0, 0, -1, 0);
|
|
layout->setSpacing(3);
|
|
m_widget->setLayout(layout);
|
|
|
|
m_widget->setFocusProxy(m_volumeSlider);
|
|
m_widget->setFocusPolicy(Qt::TabFocus);
|
|
|
|
setDefaultWidget(m_widget.get());
|
|
}
|
|
|
|
void VolumeSliderWidgetAction::updateLabelValue(bool checkMouseButtons) {
|
|
if (checkMouseButtons && MumbleApplication::instance()->mouseButtons() != Qt::NoButton) {
|
|
// Do not update the label while the user is dragging the slider.
|
|
// This will otherwise cause a glitchy experience.
|
|
return;
|
|
}
|
|
|
|
m_label->setText(QString("%01dB").arg(m_volumeSlider->value()));
|
|
}
|
|
|
|
void VolumeSliderWidgetAction::updateSliderValue(float value) {
|
|
int dbShift = VolumeAdjustment::toIntegerDBAdjustment(value);
|
|
m_volumeSlider->setValue(dbShift);
|
|
updateTooltip(dbShift);
|
|
updateLabelValue(false);
|
|
}
|
|
|
|
void VolumeSliderWidgetAction::updateTooltip(int value) {
|
|
// ToolTip on hover
|
|
QString tooltipText = QString("%1: %2%3 dB");
|
|
m_volumeSlider->setToolTip(
|
|
tooltipText.arg(tr("Volume Adjustment")).arg(value > 0 ? QString("+") : QString("")).arg(value));
|
|
}
|
|
|
|
void VolumeSliderWidgetAction::displayTooltip(int value) {
|
|
// ToolTip on drag
|
|
QString tooltipText = QString("%1%2 dB");
|
|
QToolTip::showText(QCursor::pos(), tooltipText.arg(value > 0 ? QString("+") : QString("")).arg(value), nullptr);
|
|
}
|