File indexing completed on 2024-05-12 12:21:06
0001 // SPDX-FileCopyrightText: 2006-2022 Ricardo Villalba <rvm@escomposlinux.org> 0002 // 0003 // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Trolltech-FreeQtFoundation-Accepted-LGPL 0004 0005 #include "Slider.h" 0006 #include <QApplication> 0007 #include <QMouseEvent> 0008 #include <QStyle> 0009 #include <QStyleOption> 0010 0011 Slider::Slider(QWidget *parent) 0012 : QSlider(parent) 0013 { 0014 setOrientation(Qt::Horizontal); 0015 setMouseTracking(true); // mouseMoveEvent without press. 0016 } 0017 0018 // Function copied from qslider.cpp 0019 inline int Slider::pick(const QPoint &pt) const 0020 { 0021 return orientation() == Qt::Horizontal ? pt.x() : pt.y(); 0022 } 0023 0024 // Function copied from qslider.cpp and modified to make it compile 0025 void Slider::initStyleOption_Qt430(QStyleOptionSlider *option) const 0026 { 0027 if (!option) 0028 return; 0029 0030 option->initFrom(this); 0031 option->subControls = QStyle::SC_None; 0032 option->activeSubControls = QStyle::SC_None; 0033 option->orientation = orientation(); 0034 option->maximum = maximum(); 0035 option->minimum = minimum(); 0036 option->tickPosition = (QSlider::TickPosition)tickPosition(); 0037 option->tickInterval = tickInterval(); 0038 option->upsideDown = (orientation() == Qt::Horizontal) ? (invertedAppearance() != (option->direction == Qt::RightToLeft)) 0039 : (!invertedAppearance()); 0040 option->direction = Qt::LeftToRight; // we use the upsideDown option instead 0041 option->sliderPosition = sliderPosition(); 0042 option->sliderValue = value(); 0043 option->singleStep = singleStep(); 0044 option->pageStep = pageStep(); 0045 if (orientation() == Qt::Horizontal) 0046 option->state |= QStyle::State_Horizontal; 0047 } 0048 0049 // Function copied from qslider.cpp and modified to make it compile 0050 int Slider::pixelPosToRangeValue(int pos) const 0051 { 0052 QStyleOptionSlider opt; 0053 initStyleOption(&opt); 0054 QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); 0055 QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); 0056 int sliderMin, sliderMax, sliderLength; 0057 if (orientation() == Qt::Horizontal) { 0058 sliderLength = sr.width(); 0059 sliderMin = gr.x(); 0060 sliderMax = gr.right() - sliderLength + 1; 0061 } else { 0062 sliderLength = sr.height(); 0063 sliderMin = gr.y(); 0064 sliderMax = gr.bottom() - sliderLength + 1; 0065 } 0066 return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, 0067 sliderMax - sliderMin, opt.upsideDown); 0068 } 0069 0070 void Slider::enterEvent(QEvent *event) 0071 { 0072 Q_EMIT onEnter(); 0073 QSlider::enterEvent(event); 0074 } 0075 0076 void Slider::leaveEvent(QEvent *e) 0077 { 0078 Q_EMIT onLeave(); 0079 QSlider::leaveEvent(e); 0080 } 0081 0082 void Slider::mouseMoveEvent(QMouseEvent *e) 0083 { 0084 const int o = style()->pixelMetric(QStyle::PM_SliderLength) - 1; 0085 int v = QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().x() - o / 2, width() - o, false); 0086 Q_EMIT onHover(e->globalPos(), v); 0087 QSlider::mouseMoveEvent(e); 0088 } 0089 0090 // Based on code from qslider.cpp 0091 void Slider::mousePressEvent(QMouseEvent *e) 0092 { 0093 if (e->button() == Qt::LeftButton) { 0094 QStyleOptionSlider opt; 0095 initStyleOption(&opt); 0096 const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); 0097 const QPoint center = sliderRect.center() - sliderRect.topLeft(); 0098 // to take half of the slider off for the setSliderPosition call we use the center - topLeft 0099 0100 if (!sliderRect.contains(e->pos())) { 0101 e->accept(); 0102 0103 int v = pixelPosToRangeValue(pick(e->pos() - center)); 0104 setSliderPosition(v); 0105 triggerAction(SliderMove); 0106 setRepeatAction(SliderNoAction); 0107 Q_EMIT sliderMoved(v); 0108 Q_EMIT sliderPressed(); 0109 } else { 0110 QSlider::mousePressEvent(e); 0111 } 0112 } else { 0113 QSlider::mousePressEvent(e); 0114 } 0115 } 0116 0117 #include "moc_Slider.cpp"