From 9f46b9c51c27f581cd403c18db143a557d9eba04 Mon Sep 17 00:00:00 2001 From: Goffredo Baroncelli Date: Wed, 11 Jan 2023 20:22:51 +0100 Subject: [PATCH] plugin-volume: add support for hires wheel Some mouses send a lot of events with "small" movement of the wheel. This invalidate some evaluation of the total stroke of the wheel. In the Volume Control plugin, the volume was computed on the basis of the following formula: new_volume = old_volume + event->angleDelta().y() / QWheelEvent::DefaultDeltasPerStep * volumeSlider->singleStep() However if event->angleDelta().y() is smaller than QWheelEvent::DefaultDeltasPerStep, their ratio is a value less than 1, which is zero when the math is integer based. To avoid this issue the volumeSlider->singleStep() will be increased by a factor of 1000 and the multiplication will be performed before the division. Of course all others computation will be scaled according: - the range of the volume slider will be 0..100*1000 (where previous was 0..100) - the volume will be computed as: volume = slider->value() / 1000 - slider->singleStep will be increased by a factor of 1000 --- plugin-volume/volumepopup.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/plugin-volume/volumepopup.cpp b/plugin-volume/volumepopup.cpp index 4b85363ec..33498755c 100644 --- a/plugin-volume/volumepopup.cpp +++ b/plugin-volume/volumepopup.cpp @@ -62,10 +62,9 @@ VolumePopup::VolumePopup(QWidget* parent): m_volumeSlider = new QSlider(Qt::Vertical, this); m_volumeSlider->setTickPosition(QSlider::TicksBothSides); - m_volumeSlider->setTickInterval(10); - // the volume slider shows 0-100 and volumes of all devices - // should be converted to percentages. - m_volumeSlider->setRange(0, 100); + m_volumeSlider->setTickInterval(10 * 1000); + // volume is in the range 0..100, and the slider is in the range 0..100*1000 + m_volumeSlider->setRange(0, 100 * 1000); m_volumeSlider->installEventFilter(this); m_muteToggleButton = new QPushButton(this); @@ -126,7 +125,8 @@ void VolumePopup::handleSliderValueChanged(int value) if (!m_device) return; // qDebug("VolumePopup::handleSliderValueChanged: %d\n", value); - m_device->setVolume(value); + // volume is in the range 0..100, and the slider is in the range 0..100*1000 + m_device->setVolume(value / 1000); QTimer::singleShot(0, this, [this] { QToolTip::showText(QCursor::pos(), m_volumeSlider->toolTip()); }); } @@ -140,13 +140,14 @@ void VolumePopup::handleMuteToggleClicked() void VolumePopup::handleDeviceVolumeChanged(int volume) { - // qDebug() << "handleDeviceVolumeChanged" << "volume" << volume << "max" << max; + // qDebug() << "handleDeviceVolumeChanged" << "volume" << volume; // calling m_volumeSlider->setValue will trigger // handleSliderValueChanged(), which set the device volume // again, so we have to block the signals to avoid recursive // signal emission. m_volumeSlider->blockSignals(true); - m_volumeSlider->setValue(volume); + // volume is in the range 0..100, and the slider is in the range 0..100*1000 + m_volumeSlider->setValue(volume * 1000); m_volumeSlider->setToolTip(QStringLiteral("%1%").arg(volume)); dynamic_cast(*parent()).setToolTip(m_volumeSlider->toolTip()); //parent is the button on panel m_volumeSlider->blockSignals(false); @@ -198,7 +199,9 @@ void VolumePopup::openAt(QPoint pos, Qt::Corner anchor) void VolumePopup::handleWheelEvent(QWheelEvent *event) { m_volumeSlider->setSliderPosition(m_volumeSlider->sliderPosition() - + (event->angleDelta().y() / QWheelEvent::DefaultDeltasPerStep * m_volumeSlider->singleStep())); + + (event->angleDelta().y() * + m_volumeSlider->singleStep() / + QWheelEvent::DefaultDeltasPerStep)); } void VolumePopup::setDevice(AudioDevice *device) @@ -225,6 +228,7 @@ void VolumePopup::setDevice(AudioDevice *device) void VolumePopup::setSliderStep(int step) { + step *= 1000; // step is in range 0..100 m_volumeSlider->setSingleStep(step); m_volumeSlider->setPageStep(step * 10); }