Skip to content

Commit

Permalink
plugin-volume: add support for hires wheel
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kreijack committed Jan 11, 2023
1 parent 38c8a8d commit 9f46b9c
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions plugin-volume/volumepopup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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()); });
}

Expand All @@ -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<QWidget&>(*parent()).setToolTip(m_volumeSlider->toolTip()); //parent is the button on panel
m_volumeSlider->blockSignals(false);
Expand Down Expand Up @@ -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)
Expand All @@ -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);
}
Expand Down

0 comments on commit 9f46b9c

Please sign in to comment.