File indexing completed on 2024-04-28 04:21:26

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"