652 lines
21 KiB
C++
652 lines
21 KiB
C++
/*
|
|
* This file is part of Pastie
|
|
*
|
|
* Pastie 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 3 of the License, or
|
|
* any later version.
|
|
*
|
|
* Pastie is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Pastie. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
/**
|
|
* @copyright Kitware Inc.
|
|
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
|
|
* @author Steffen Vogel <steffen.vogel@rwth-aachen.de>
|
|
* @link http://www.steffenvogel.de
|
|
* @package CTK
|
|
*/
|
|
|
|
// Qt includes
|
|
#include <QDebug>
|
|
#include <QMouseEvent>
|
|
#include <QKeyEvent>
|
|
#include <QStyleOptionSlider>
|
|
#include <QApplication>
|
|
#include <QStylePainter>
|
|
#include <QStyle>
|
|
#include <QToolTip>
|
|
|
|
#include "RangeSlider.h"
|
|
|
|
class RangeSliderPrivate
|
|
{
|
|
Q_DECLARE_PUBLIC(RangeSlider);
|
|
|
|
protected:
|
|
RangeSlider* const q_ptr;
|
|
|
|
public:
|
|
/// Boolean indicates the selected handle
|
|
/// True for the minimum range handle, false for the maximum range handle
|
|
enum Handle {
|
|
NoHandle = 0x0,
|
|
MinimumHandle = 0x1,
|
|
MaximumHandle = 0x2
|
|
};
|
|
Q_DECLARE_FLAGS(Handles, Handle);
|
|
|
|
RangeSliderPrivate(RangeSlider& object);
|
|
void init();
|
|
|
|
/// Return the handle at the given pos, or none if no handle is at the pos.
|
|
/// If a handle is selected, handleRect is set to the handle rect.
|
|
/// otherwise return NoHandle and handleRect is set to the combined rect of
|
|
/// the min and max handles
|
|
Handle handleAtPos(const QPoint& pos, QRect& handleRect) const;
|
|
|
|
/// Copied verbatim from QSliderPrivate class (see QSlider.cpp)
|
|
int pixelPosToRangeValue(int pos) const;
|
|
int pixelPosFromRangeValue(int val) const;
|
|
|
|
/// Draw the bottom and top sliders.
|
|
void drawHandle(QStylePainter* painter, enum Handle handle) const;
|
|
|
|
/// End points of the range on the Model
|
|
int maximumValue;
|
|
int minimumValue;
|
|
|
|
/// End points of the range on the GUI. This is synced with the model.
|
|
int maximumPosition;
|
|
int minimumPosition;
|
|
|
|
/// Controls selected ?
|
|
QStyle::SubControl minimumSliderSelected;
|
|
QStyle::SubControl maximumSliderSelected;
|
|
|
|
/// See QSliderPrivate::clickOffset.
|
|
/// Overrides this ivar
|
|
int subclassClickOffset;
|
|
|
|
/// See QSliderPrivate::position
|
|
/// Overrides this ivar.
|
|
int subclassPosition;
|
|
|
|
/// Original width between the 2 bounds before any moves
|
|
float subclassWidth;
|
|
|
|
RangeSliderPrivate::Handles selectedHandles;
|
|
|
|
QString handleToolTip;
|
|
|
|
private:
|
|
Q_DISABLE_COPY(RangeSliderPrivate);
|
|
};
|
|
|
|
RangeSliderPrivate::RangeSliderPrivate(RangeSlider& object) :
|
|
q_ptr(&object),
|
|
maximumValue(100),
|
|
minimumValue(0),
|
|
maximumPosition(100),
|
|
minimumPosition(0),
|
|
minimumSliderSelected(QStyle::SC_None),
|
|
maximumSliderSelected(QStyle::SC_None),
|
|
subclassClickOffset(0),
|
|
subclassPosition(0),
|
|
subclassWidth(0),
|
|
selectedHandles(0)
|
|
{ }
|
|
|
|
void RangeSliderPrivate::init()
|
|
{
|
|
Q_Q(RangeSlider);
|
|
minimumValue = q->minimum();
|
|
maximumValue = q->maximum();
|
|
minimumPosition = q->minimum();
|
|
maximumPosition = q->maximum();
|
|
q->connect(q, SIGNAL(rangeChanged(int,int)), q, SLOT(onRangeChanged(int,int)));
|
|
}
|
|
|
|
RangeSliderPrivate::Handle RangeSliderPrivate::handleAtPos(const QPoint& pos, QRect& handleRect) const
|
|
{
|
|
Q_Q(const RangeSlider);
|
|
|
|
QStyleOptionSlider option;
|
|
q->initStyleOption(&option);
|
|
|
|
// The functinos hitTestComplexControl only know about 1 handle. As we have
|
|
// 2, we change the position of the handle and test if the pos correspond to
|
|
// any of the 2 positions.
|
|
|
|
// Test the MinimumHandle
|
|
option.sliderPosition = minimumPosition;
|
|
option.sliderValue = minimumValue;
|
|
|
|
QStyle::SubControl minimumControl = q->style()->hitTestComplexControl(
|
|
QStyle::CC_Slider, &option, pos, q);
|
|
QRect minimumHandleRect = q->style()->subControlRect(
|
|
QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, q);
|
|
|
|
// Test if the pos is under the Maximum handle
|
|
option.sliderPosition = maximumPosition;
|
|
option.sliderValue = maximumValue;
|
|
|
|
QStyle::SubControl maximumControl = q->style()->hitTestComplexControl(
|
|
QStyle::CC_Slider, &option, pos, q);
|
|
QRect maximumHandleRect = q->style()->subControlRect(
|
|
QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, q);
|
|
|
|
// The pos is above both handles, select the closest handle
|
|
if (minimumControl == QStyle::SC_SliderHandle &&
|
|
maximumControl == QStyle::SC_SliderHandle) {
|
|
int minDist = 0;
|
|
int maxDist = 0;
|
|
if (q->orientation() == Qt::Horizontal) {
|
|
minDist = pos.x() - minimumHandleRect.left();
|
|
maxDist = maximumHandleRect.right() - pos.x();
|
|
}
|
|
else if (q->orientation() == Qt::Vertical) {
|
|
minDist = minimumHandleRect.bottom() - pos.y();
|
|
maxDist = pos.y() - maximumHandleRect.top();
|
|
}
|
|
Q_ASSERT(minDist >= 0 && maxDist >= 0);
|
|
minimumControl = minDist < maxDist ? minimumControl : QStyle::SC_None;
|
|
}
|
|
|
|
if (minimumControl == QStyle::SC_SliderHandle) {
|
|
handleRect = minimumHandleRect;
|
|
return MinimumHandle;
|
|
}
|
|
else if (maximumControl == QStyle::SC_SliderHandle) {
|
|
handleRect = maximumHandleRect;
|
|
return MaximumHandle;
|
|
}
|
|
|
|
handleRect = minimumHandleRect.united(maximumHandleRect);
|
|
return NoHandle;
|
|
}
|
|
|
|
int RangeSliderPrivate::pixelPosToRangeValue(int pos) const
|
|
{
|
|
Q_Q(const RangeSlider);
|
|
QStyleOptionSlider option;
|
|
q->initStyleOption(&option);
|
|
|
|
QRect gr = q->style()->subControlRect(QStyle::CC_Slider,
|
|
&option,
|
|
QStyle::SC_SliderGroove,
|
|
q);
|
|
QRect sr = q->style()->subControlRect(QStyle::CC_Slider,
|
|
&option,
|
|
QStyle::SC_SliderHandle,
|
|
q);
|
|
int sliderMin, sliderMax, sliderLength;
|
|
if (option.orientation == Qt::Horizontal) {
|
|
sliderLength = sr.width();
|
|
sliderMin = gr.x();
|
|
sliderMax = gr.right() - sliderLength + 1;
|
|
}
|
|
else {
|
|
sliderLength = sr.height();
|
|
sliderMin = gr.y();
|
|
sliderMax = gr.bottom() - sliderLength + 1;
|
|
}
|
|
|
|
return QStyle::sliderValueFromPosition(q->minimum(),
|
|
q->maximum(),
|
|
pos - sliderMin,
|
|
sliderMax - sliderMin,
|
|
option.upsideDown);
|
|
}
|
|
|
|
int RangeSliderPrivate::pixelPosFromRangeValue(int val) const
|
|
{
|
|
Q_Q(const RangeSlider);
|
|
QStyleOptionSlider option;
|
|
q->initStyleOption(&option);
|
|
|
|
QRect gr = q->style()->subControlRect(QStyle::CC_Slider,
|
|
&option,
|
|
QStyle::SC_SliderGroove,
|
|
q);
|
|
QRect sr = q->style()->subControlRect(QStyle::CC_Slider,
|
|
&option,
|
|
QStyle::SC_SliderHandle,
|
|
q);
|
|
int sliderMin, sliderMax, sliderLength;
|
|
if (option.orientation == Qt::Horizontal) {
|
|
sliderLength = sr.width();
|
|
sliderMin = gr.x();
|
|
sliderMax = gr.right() - sliderLength + 1;
|
|
}
|
|
else
|
|
{
|
|
sliderLength = sr.height();
|
|
sliderMin = gr.y();
|
|
sliderMax = gr.bottom() - sliderLength + 1;
|
|
}
|
|
|
|
return QStyle::sliderPositionFromValue(q->minimum(),
|
|
q->maximum(),
|
|
val,
|
|
sliderMax - sliderMin,
|
|
option.upsideDown) + sliderMin;
|
|
}
|
|
|
|
void RangeSliderPrivate::drawHandle(QStylePainter* painter, enum Handle handle) const
|
|
{
|
|
Q_Q(const RangeSlider);
|
|
QStyleOptionSlider option;
|
|
q->initMinimumSliderStyleOption(&option);
|
|
|
|
option.subControls = QStyle::SC_SliderHandle;
|
|
option.sliderValue = (handle == MinimumHandle) ? minimumValue : maximumValue;
|
|
option.sliderPosition = (handle == MinimumHandle) ? minimumPosition : maximumPosition;
|
|
|
|
if ((handle == MinimumHandle && q->isMinimumSliderDown()) ||
|
|
(handle == MaximumHandle && q->isMinimumSliderDown())) {
|
|
option.activeSubControls = QStyle::SC_SliderHandle;
|
|
option.state |= QStyle::State_Sunken;
|
|
}
|
|
|
|
#ifdef Q_OS_MAC
|
|
// On mac style, drawing just the handle actually draws also the groove.
|
|
QRect clip = q->style()->subControlRect(QStyle::CC_Slider, &option,
|
|
QStyle::SC_SliderHandle, q);
|
|
clip.adjust(+2, +2, -2, -2);
|
|
painter->setClipRect(clip);
|
|
#endif
|
|
painter->drawComplexControl(QStyle::CC_Slider, option);
|
|
}
|
|
|
|
RangeSlider::RangeSlider(QWidget* _parent) :
|
|
QSlider(_parent),
|
|
d_ptr(new RangeSliderPrivate(*this))
|
|
{
|
|
Q_D(RangeSlider);
|
|
d->init();
|
|
}
|
|
|
|
RangeSlider::RangeSlider(Qt::Orientation o, QWidget* parentObject) :
|
|
QSlider(o, parentObject),
|
|
d_ptr(new RangeSliderPrivate(*this))
|
|
{
|
|
Q_D(RangeSlider);
|
|
d->init();
|
|
}
|
|
|
|
RangeSlider::RangeSlider(RangeSliderPrivate* impl, QWidget* _parent) :
|
|
QSlider(_parent),
|
|
d_ptr(impl)
|
|
{
|
|
Q_D(RangeSlider);
|
|
d->init();
|
|
}
|
|
|
|
RangeSlider::RangeSlider(RangeSliderPrivate* impl, Qt::Orientation o, QWidget* parentObject) :
|
|
QSlider(o, parentObject),
|
|
d_ptr(impl)
|
|
{
|
|
Q_D(RangeSlider);
|
|
d->init();
|
|
}
|
|
|
|
RangeSlider::~RangeSlider()
|
|
{ }
|
|
|
|
int RangeSlider::minimumValue() const
|
|
{
|
|
Q_D(const RangeSlider);
|
|
return d->minimumValue;
|
|
}
|
|
|
|
void RangeSlider::setMinimumValue(int min)
|
|
{
|
|
Q_D(RangeSlider);
|
|
setValues(min, qMax(d->maximumValue,min));
|
|
}
|
|
|
|
int RangeSlider::maximumValue() const
|
|
{
|
|
Q_D(const RangeSlider);
|
|
return d->maximumValue;
|
|
}
|
|
|
|
void RangeSlider::setMaximumValue(int max)
|
|
{
|
|
Q_D(RangeSlider);
|
|
setValues(qMin(d->minimumValue, max), max);
|
|
}
|
|
|
|
void RangeSlider::setValues(int l, int u)
|
|
{
|
|
Q_D(RangeSlider);
|
|
const int minValue = qBound(minimum(), qMin(l,u), maximum());
|
|
const int maxValue = qBound(minimum(), qMax(l,u), maximum());
|
|
|
|
bool emitMinValChanged = (minValue != d->minimumValue);
|
|
bool emitMaxValChanged = (maxValue != d->maximumValue);
|
|
|
|
d->minimumValue = minValue;
|
|
d->maximumValue = maxValue;
|
|
|
|
bool emitMinPosChanged = (minValue != d->minimumPosition);
|
|
bool emitMaxPosChanged = (maxValue != d->maximumPosition);
|
|
|
|
d->minimumPosition = minValue;
|
|
d->maximumPosition = maxValue;
|
|
|
|
if (isSliderDown()) {
|
|
if (emitMinPosChanged)
|
|
emit minimumPositionChanged(d->minimumPosition);
|
|
if (emitMaxPosChanged)
|
|
emit maximumPositionChanged(d->maximumPosition);
|
|
if (emitMaxPosChanged || emitMinPosChanged)
|
|
emit positionsChanged(d->minimumPosition, d->maximumPosition);
|
|
}
|
|
|
|
if (emitMinValChanged)
|
|
emit minimumValueChanged(d->minimumValue);
|
|
if (emitMaxValChanged)
|
|
emit maximumValueChanged(d->maximumValue);
|
|
if (emitMaxValChanged || emitMinValChanged)
|
|
emit valuesChanged(d->minimumValue, d->maximumValue);
|
|
|
|
if (emitMinPosChanged || emitMaxPosChanged ||
|
|
emitMinValChanged || emitMaxValChanged) {
|
|
update();
|
|
}
|
|
}
|
|
|
|
int RangeSlider::minimumPosition() const
|
|
{
|
|
Q_D(const RangeSlider);
|
|
return d->minimumPosition;
|
|
}
|
|
|
|
int RangeSlider::maximumPosition() const
|
|
{
|
|
Q_D(const RangeSlider);
|
|
return d->maximumPosition;
|
|
}
|
|
|
|
void RangeSlider::setMinimumPosition(int l)
|
|
{
|
|
Q_D(const RangeSlider);
|
|
setPositions(l, qMax(l, d->maximumPosition));
|
|
}
|
|
|
|
void RangeSlider::setMaximumPosition(int u)
|
|
{
|
|
Q_D(const RangeSlider);
|
|
setPositions(qMin(d->minimumPosition, u), u);
|
|
}
|
|
|
|
void RangeSlider::setPositions(int min, int max)
|
|
{
|
|
Q_D(RangeSlider);
|
|
const int minPosition = qBound(minimum(), qMin(min, max), maximum());
|
|
const int maxPosition = qBound(minimum(), qMax(min, max), maximum());
|
|
|
|
bool emitMinPosChanged = (minPosition != d->minimumPosition);
|
|
bool emitMaxPosChanged = (maxPosition != d->maximumPosition);
|
|
|
|
if (!emitMinPosChanged && !emitMaxPosChanged)
|
|
return;
|
|
|
|
d->minimumPosition = minPosition;
|
|
d->maximumPosition = maxPosition;
|
|
|
|
if (!hasTracking())
|
|
update();
|
|
|
|
if (isSliderDown()) {
|
|
if (emitMinPosChanged)
|
|
emit minimumPositionChanged(d->minimumPosition);
|
|
if (emitMaxPosChanged)
|
|
emit maximumPositionChanged(d->maximumPosition);
|
|
if (emitMaxPosChanged || emitMinPosChanged)
|
|
emit positionsChanged(d->minimumPosition, d->maximumPosition);
|
|
}
|
|
|
|
if (hasTracking()) {
|
|
triggerAction(SliderMove);
|
|
setValues(d->minimumPosition, d->maximumPosition);
|
|
}
|
|
}
|
|
|
|
void RangeSlider::onRangeChanged(int _minimum, int _maximum)
|
|
{
|
|
Q_UNUSED(_minimum);
|
|
Q_UNUSED(_maximum);
|
|
Q_D(RangeSlider);
|
|
setValues(d->minimumValue, d->maximumValue);
|
|
}
|
|
|
|
void RangeSlider::paintEvent(QPaintEvent*)
|
|
{
|
|
Q_D(RangeSlider);
|
|
QStyleOptionSlider option;
|
|
initStyleOption(&option);
|
|
|
|
QStylePainter painter(this);
|
|
option.subControls = QStyle::SC_SliderGroove;
|
|
// Move to minimum to not highlight the SliderGroove.
|
|
// On mac style, drawing just the slider groove also draws the handles,
|
|
// therefore we give a negative (outside of view) position.
|
|
option.sliderValue = minimum() - maximum();
|
|
option.sliderPosition = minimum() - maximum();
|
|
painter.drawComplexControl(QStyle::CC_Slider, option);
|
|
|
|
option.sliderPosition = d->minimumPosition;
|
|
const QRect lr = style()->subControlRect(QStyle::CC_Slider,
|
|
&option,
|
|
QStyle::SC_SliderHandle,
|
|
this);
|
|
option.sliderPosition = d->maximumPosition;
|
|
|
|
const QRect ur = style()->subControlRect(QStyle::CC_Slider,
|
|
&option,
|
|
QStyle::SC_SliderHandle,
|
|
this);
|
|
|
|
QRect groove = style()->subControlRect(QStyle::CC_Slider,
|
|
&option,
|
|
QStyle::SC_SliderGroove,
|
|
this);
|
|
|
|
QRect rangeBox;
|
|
if (option.orientation == Qt::Horizontal)
|
|
rangeBox = QRect(
|
|
QPoint(qMin(lr.center().x(), ur.center().x()), groove.center().y() - 2),
|
|
QPoint(qMax(lr.center().x(), ur.center().x()), groove.center().y() + 1));
|
|
else
|
|
rangeBox = QRect(
|
|
QPoint(groove.center().x() - 2, qMin(lr.center().y(), ur.center().y())),
|
|
QPoint(groove.center().x() + 1, qMax(lr.center().y(), ur.center().y())));
|
|
|
|
|
|
groove.adjust(0, 0, -1, 0);
|
|
|
|
// Create default colors based on the transfer function.
|
|
QColor highlight = palette().color(QPalette::Normal, QPalette::Highlight);
|
|
QLinearGradient gradient;
|
|
if (option.orientation == Qt::Horizontal) {
|
|
gradient = QLinearGradient(groove.center().x(), groove.top(),
|
|
groove.center().x(), groove.bottom());
|
|
}
|
|
else {
|
|
gradient = QLinearGradient(groove.left(), groove.center().y(),
|
|
groove.right(), groove.center().y());
|
|
}
|
|
|
|
gradient.setColorAt(0, highlight.darker(120));
|
|
gradient.setColorAt(1, highlight.lighter(160));
|
|
|
|
painter.setPen(QPen(highlight.darker(150), 0));
|
|
painter.setBrush(gradient);
|
|
painter.drawRect(rangeBox.intersected(groove));
|
|
|
|
if (isMinimumSliderDown()) {
|
|
d->drawHandle(&painter, RangeSliderPrivate::MaximumHandle);
|
|
d->drawHandle(&painter, RangeSliderPrivate::MinimumHandle);
|
|
}
|
|
else {
|
|
d->drawHandle(&painter, RangeSliderPrivate::MinimumHandle);
|
|
d->drawHandle(&painter, RangeSliderPrivate::MaximumHandle);
|
|
}
|
|
}
|
|
|
|
void RangeSlider::mousePressEvent(QMouseEvent* mouseEvent)
|
|
{
|
|
Q_D(RangeSlider);
|
|
if (minimum() == maximum() || (mouseEvent->buttons() ^ mouseEvent->button())) {
|
|
mouseEvent->ignore();
|
|
return;
|
|
}
|
|
|
|
int mepos = orientation() == Qt::Horizontal ?
|
|
mouseEvent->pos().x() : mouseEvent->pos().y();
|
|
|
|
QStyleOptionSlider option;
|
|
initStyleOption(&option);
|
|
|
|
QRect handleRect;
|
|
RangeSliderPrivate::Handle handle_ = d->handleAtPos(mouseEvent->pos(), handleRect);
|
|
|
|
if (handle_ != RangeSliderPrivate::NoHandle) {
|
|
d->subclassPosition = (handle_ == RangeSliderPrivate::MinimumHandle)?
|
|
d->minimumPosition : d->maximumPosition;
|
|
|
|
// save the position of the mouse inside the handle for later
|
|
d->subclassClickOffset = mepos - (orientation() == Qt::Horizontal ?
|
|
handleRect.left() : handleRect.top());
|
|
|
|
setSliderDown(true);
|
|
|
|
if (d->selectedHandles != handle_) {
|
|
d->selectedHandles = handle_;
|
|
update(handleRect);
|
|
}
|
|
// Accept the mouseEvent
|
|
mouseEvent->accept();
|
|
return;
|
|
}
|
|
|
|
// if we are here, no handles have been pressed
|
|
// Check if we pressed on the groove between the 2 handles
|
|
|
|
QStyle::SubControl control = style()->hitTestComplexControl(
|
|
QStyle::CC_Slider, &option, mouseEvent->pos(), this);
|
|
QRect sr = style()->subControlRect(
|
|
QStyle::CC_Slider, &option, QStyle::SC_SliderGroove, this);
|
|
int minCenter = (orientation() == Qt::Horizontal ?
|
|
handleRect.left() : handleRect.top());
|
|
int maxCenter = (orientation() == Qt::Horizontal ?
|
|
handleRect.right() : handleRect.bottom());
|
|
if (control == QStyle::SC_SliderGroove && mepos > minCenter && mepos < maxCenter) {
|
|
// warning lost of precision it might be fatal
|
|
d->subclassPosition = (d->minimumPosition + d->maximumPosition) / 2.;
|
|
d->subclassClickOffset = mepos - d->pixelPosFromRangeValue(d->subclassPosition);
|
|
d->subclassWidth = (d->maximumPosition - d->minimumPosition) / 2.;
|
|
qMax(d->subclassPosition - d->minimumPosition, d->maximumPosition - d->subclassPosition);
|
|
setSliderDown(true);
|
|
if (!isMinimumSliderDown() || !isMaximumSliderDown()) {
|
|
d->selectedHandles =
|
|
QFlags<RangeSliderPrivate::Handle>(RangeSliderPrivate::MinimumHandle) |
|
|
QFlags<RangeSliderPrivate::Handle>(RangeSliderPrivate::MaximumHandle);
|
|
update(handleRect.united(sr));
|
|
}
|
|
|
|
mouseEvent->accept();
|
|
return;
|
|
}
|
|
mouseEvent->ignore();
|
|
}
|
|
|
|
void RangeSlider::mouseMoveEvent(QMouseEvent* mouseEvent)
|
|
{
|
|
Q_D(RangeSlider);
|
|
if (!d->selectedHandles) {
|
|
mouseEvent->ignore();
|
|
return;
|
|
}
|
|
int mepos = orientation() == Qt::Horizontal ?
|
|
mouseEvent->pos().x() : mouseEvent->pos().y();
|
|
|
|
QStyleOptionSlider option;
|
|
initStyleOption(&option);
|
|
|
|
const int m = style()->pixelMetric(QStyle::PM_MaximumDragDistance, &option, this);
|
|
|
|
int newPosition = d->pixelPosToRangeValue(mepos - d->subclassClickOffset);
|
|
|
|
if (m >= 0) {
|
|
const QRect r = rect().adjusted(-m, -m, m, m);
|
|
if (!r.contains(mouseEvent->pos()))
|
|
newPosition = d->subclassPosition;
|
|
}
|
|
|
|
if (isMinimumSliderDown() && !isMaximumSliderDown()) {
|
|
double newMinPos = qMin(newPosition,d->maximumPosition);
|
|
setPositions(newMinPos, d->maximumPosition);
|
|
}
|
|
else if (isMaximumSliderDown() && !isMinimumSliderDown()) {
|
|
double newMaxPos = qMax(d->minimumPosition, newPosition);
|
|
setPositions(d->minimumPosition, newMaxPos);
|
|
}
|
|
else if (isMinimumSliderDown() && isMaximumSliderDown()) {
|
|
setPositions(newPosition - static_cast<int>(d->subclassWidth),
|
|
newPosition + static_cast<int>(d->subclassWidth + .5));
|
|
}
|
|
|
|
mouseEvent->accept();
|
|
}
|
|
|
|
void RangeSlider::mouseReleaseEvent(QMouseEvent* mouseEvent)
|
|
{
|
|
Q_D(RangeSlider);
|
|
QSlider::mouseReleaseEvent(mouseEvent);
|
|
|
|
setSliderDown(false);
|
|
d->selectedHandles = 0;
|
|
|
|
setValues(d->minimumPosition, d->maximumPosition);
|
|
}
|
|
|
|
bool RangeSlider::isMinimumSliderDown() const
|
|
{
|
|
Q_D(const RangeSlider);
|
|
return d->selectedHandles & RangeSliderPrivate::MinimumHandle;
|
|
}
|
|
|
|
bool RangeSlider::isMaximumSliderDown() const
|
|
{
|
|
Q_D(const RangeSlider);
|
|
return d->selectedHandles & RangeSliderPrivate::MaximumHandle;
|
|
}
|
|
|
|
void RangeSlider::initMinimumSliderStyleOption(QStyleOptionSlider* option) const
|
|
{
|
|
initStyleOption(option);
|
|
}
|
|
|
|
void RangeSlider::initMaximumSliderStyleOption(QStyleOptionSlider* option) const
|
|
{
|
|
initStyleOption(option);
|
|
}
|