/*************************************************************************** sliderslider.cpp ------------------- begin : Dec 15 2003 copyright : (C) 2003 by Mark Kretschmann email : markey@web.de copyright : (C) 2005 by Gábor Lehel email : illissius@gmail.com copyright : (C) 2018-2023 by Jonas Kvinge email : jonas@jkvinge.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include "sliderslider.h" SliderSlider::SliderSlider(const Qt::Orientation orientation, QWidget *parent, const int max) : QSlider(orientation, parent), sliding_(false), wheeling_(false), outside_(false), prev_value_(0) { setRange(0, max); } void SliderSlider::SetValue(const uint value) { setValue(static_cast(value)); } void SliderSlider::setValue(int value) { // Don't adjust the slider while the user is dragging it! if ((!sliding_ || outside_) && !wheeling_) { QSlider::setValue(adjustValue(value)); } else { prev_value_ = value; } } int SliderSlider::adjustValue(int v) const { int mp = (minimum() + maximum()) / 2; return orientation() == Qt::Vertical ? mp - (v - mp) : v; } void SliderSlider::slideEvent(QMouseEvent *e) { QStyleOptionSlider option; initStyleOption(&option); QRect sliderRect(style()->subControlRect(QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, this)); QSlider::setValue( orientation() == Qt::Horizontal ? ((QApplication::layoutDirection() == Qt::RightToLeft) ? QStyle::sliderValueFromPosition( minimum(), maximum(), width() - (e->pos().x() - sliderRect.width() / 2), width() + sliderRect.width(), true) : QStyle::sliderValueFromPosition( minimum(), maximum(), e->pos().x() - sliderRect.width() / 2, width() - sliderRect.width())) : QStyle::sliderValueFromPosition( minimum(), maximum(), e->pos().y() - sliderRect.height() / 2, height() - sliderRect.height())); } void SliderSlider::mouseMoveEvent(QMouseEvent *e) { if (sliding_) { // feels better, but using set value of 20 is bad of course QRect rect(-20, -20, width() + 40, height() + 40); if (orientation() == Qt::Horizontal && !rect.contains(e->pos())) { if (!outside_) QSlider::setValue(prev_value_); outside_ = true; } else { outside_ = false; slideEvent(e); emit sliderMoved(value()); } } else { QSlider::mouseMoveEvent(e); } } void SliderSlider::mousePressEvent(QMouseEvent *e) { QStyleOptionSlider option; initStyleOption(&option); QRect sliderRect(style()->subControlRect(QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, this)); sliding_ = true; prev_value_ = QSlider::value(); if (!sliderRect.contains(e->pos())) mouseMoveEvent(e); } void SliderSlider::mouseReleaseEvent(QMouseEvent*) { if (!outside_ && QSlider::value() != prev_value_) { emit SliderReleased(value()); } sliding_ = false; outside_ = false; } void SliderSlider::wheelEvent(QWheelEvent *e) { if (orientation() == Qt::Vertical) { // Will be handled by the parent widget e->ignore(); return; } wheeling_ = true; // Position Slider (horizontal) int step = e->angleDelta().y() * 1500 / 18; int nval = qBound(minimum(), QSlider::value() + step, maximum()); QSlider::setValue(nval); emit SliderReleased(value()); wheeling_ = false; }