146 lines
4.3 KiB
C++
146 lines
4.3 KiB
C++
#include "ElaScrollBarPrivate.h"
|
|
|
|
#include <QApplication>
|
|
#include <QPropertyAnimation>
|
|
#include <QStyleOption>
|
|
|
|
#include "ElaScrollBar.h"
|
|
ElaScrollBarPrivate::ElaScrollBarPrivate(QObject* parent)
|
|
: QObject{parent}
|
|
{
|
|
}
|
|
|
|
ElaScrollBarPrivate::~ElaScrollBarPrivate()
|
|
{
|
|
}
|
|
|
|
void ElaScrollBarPrivate::onRangeChanged(int min, int max)
|
|
{
|
|
Q_Q(ElaScrollBar);
|
|
if (q->isVisible() && _pIsAnimation && max != 0)
|
|
{
|
|
QPropertyAnimation* rangeSmoothAnimation = new QPropertyAnimation(this, "pTargetMaximum");
|
|
connect(rangeSmoothAnimation, &QPropertyAnimation::finished, this, [=]() {
|
|
Q_EMIT q->rangeAnimationFinished();
|
|
});
|
|
connect(rangeSmoothAnimation, &QPropertyAnimation::valueChanged, this, [=](const QVariant& value) {
|
|
q->blockSignals(true);
|
|
q->setMaximum(value.toUInt());
|
|
q->blockSignals(false);
|
|
q->update();
|
|
});
|
|
rangeSmoothAnimation->setEasingCurve(QEasingCurve::OutSine);
|
|
rangeSmoothAnimation->setDuration(250);
|
|
rangeSmoothAnimation->setStartValue(_pTargetMaximum);
|
|
rangeSmoothAnimation->setEndValue(max);
|
|
rangeSmoothAnimation->start(QAbstractAnimation::DeleteWhenStopped);
|
|
}
|
|
else
|
|
{
|
|
if (max == 0)
|
|
{
|
|
_scrollValue = -1;
|
|
}
|
|
_pTargetMaximum = max;
|
|
}
|
|
}
|
|
|
|
void ElaScrollBarPrivate::_scroll(Qt::KeyboardModifiers modifiers, int delta)
|
|
{
|
|
Q_Q(ElaScrollBar);
|
|
int stepsToScroll = 0;
|
|
qreal offset = qreal(delta) / 120;
|
|
int pageStep = 10;
|
|
int singleStep = q->singleStep();
|
|
if ((modifiers & Qt::ControlModifier) || (modifiers & Qt::ShiftModifier))
|
|
{
|
|
stepsToScroll = qBound(-pageStep, int(offset * pageStep), pageStep);
|
|
}
|
|
else
|
|
{
|
|
stepsToScroll = QApplication::wheelScrollLines() * offset * singleStep;
|
|
}
|
|
if (abs(_scrollValue - q->value()) > abs(stepsToScroll * _pSpeedLimit))
|
|
{
|
|
_scrollValue = q->value();
|
|
}
|
|
_scrollValue -= stepsToScroll;
|
|
_slideSmoothAnimation->stop();
|
|
_slideSmoothAnimation->setStartValue(q->value());
|
|
_slideSmoothAnimation->setEndValue(_scrollValue);
|
|
_slideSmoothAnimation->start();
|
|
}
|
|
|
|
int ElaScrollBarPrivate::_pixelPosToRangeValue(int pos) const
|
|
{
|
|
Q_Q(const ElaScrollBar);
|
|
QStyleOptionSlider opt;
|
|
q->initStyleOption(&opt);
|
|
QRect gr = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt,
|
|
QStyle::SC_ScrollBarGroove, q);
|
|
QRect sr = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt,
|
|
QStyle::SC_ScrollBarSlider, q);
|
|
int sliderMin, sliderMax, sliderLength;
|
|
if (q->orientation() == Qt::Horizontal)
|
|
{
|
|
sliderLength = sr.width();
|
|
sliderMin = gr.x();
|
|
sliderMax = gr.right() - sliderLength + 1;
|
|
if (q->layoutDirection() == Qt::RightToLeft)
|
|
{
|
|
opt.upsideDown = !opt.upsideDown;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sliderLength = sr.height();
|
|
sliderMin = gr.y();
|
|
sliderMax = gr.bottom() - sliderLength + 1;
|
|
}
|
|
return QStyle::sliderValueFromPosition(q->minimum(), q->maximum(), pos - sliderMin,
|
|
sliderMax - sliderMin, opt.upsideDown);
|
|
}
|
|
|
|
void ElaScrollBarPrivate::_initAllConfig()
|
|
{
|
|
Q_Q(ElaScrollBar);
|
|
_handleScrollBarRangeChanged(_originScrollBar->minimum(), _originScrollBar->maximum());
|
|
q->setSingleStep(_originScrollBar->singleStep());
|
|
q->setPageStep(_originScrollBar->pageStep());
|
|
}
|
|
|
|
void ElaScrollBarPrivate::_handleScrollBarValueChanged(QScrollBar* scrollBar, int value)
|
|
{
|
|
scrollBar->setValue(value);
|
|
}
|
|
|
|
void ElaScrollBarPrivate::_handleScrollBarRangeChanged(int min, int max)
|
|
{
|
|
Q_Q(ElaScrollBar);
|
|
q->setRange(min, max);
|
|
if (max <= 0)
|
|
{
|
|
q->setVisible(false);
|
|
}
|
|
else
|
|
{
|
|
q->setVisible(true);
|
|
}
|
|
}
|
|
|
|
void ElaScrollBarPrivate::_handleScrollBarGeometry()
|
|
{
|
|
Q_Q(ElaScrollBar);
|
|
q->raise();
|
|
q->setSingleStep(_originScrollBar->singleStep());
|
|
q->setPageStep(_originScrollBar->pageStep());
|
|
if (q->orientation() == Qt::Horizontal)
|
|
{
|
|
q->setGeometry(0, _originScrollArea->height() - 10, _originScrollArea->width(), 10);
|
|
}
|
|
else
|
|
{
|
|
q->setGeometry(_originScrollArea->width() - 10, 0, 10, _originScrollArea->height());
|
|
}
|
|
}
|