156 lines
4.4 KiB
C++
156 lines
4.4 KiB
C++
/***************************************************************************
|
|
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 <QApplication>
|
|
#include <QSlider>
|
|
#include <QStyle>
|
|
#include <QStyleOptionSlider>
|
|
#include <QMouseEvent>
|
|
#include <QWheelEvent>
|
|
|
|
#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<int>(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;
|
|
|
|
}
|