From 58f157db4b743ad4c09f1d6b70c02e47dd9dc283 Mon Sep 17 00:00:00 2001 From: laserpants Date: Thu, 12 May 2016 23:13:45 +0300 Subject: [PATCH] make slider behave nicely --- components/slider.cpp | 2 +- components/slider_p.h | 4 +- components/sliderthumb.cpp | 20 ++++++---- components/slidertrack.cpp | 75 ++++++++++++++++++++++---------------- 4 files changed, 60 insertions(+), 41 deletions(-) diff --git a/components/slider.cpp b/components/slider.cpp index 4b1e92b..9a6b672 100644 --- a/components/slider.cpp +++ b/components/slider.cpp @@ -175,7 +175,7 @@ void Slider::mousePressEvent(QMouseEvent *event) : SliderPageStepSub; triggerAction(action); - setRepeatAction(action); + setRepeatAction(action, 400, 8); } void Slider::mouseReleaseEvent(QMouseEvent *event) diff --git a/components/slider_p.h b/components/slider_p.h index 1b4b8a0..efeb5f9 100644 --- a/components/slider_p.h +++ b/components/slider_p.h @@ -3,7 +3,6 @@ #include #include -#include #include "lib/style.h" #include "slider.h" #include "slidertrack.h" @@ -48,7 +47,7 @@ SliderPrivate::SliderPrivate(Slider *parent) hoverThumb(false), hover(false), step(false), - pageStepMode(false), + pageStepMode(true), stepTo(0), oldValue(parent->value()), trackWidth(2) @@ -57,6 +56,7 @@ SliderPrivate::SliderPrivate(Slider *parent) q->setMouseTracking(true); q->setFocusPolicy(Qt::StrongFocus); + q->setPageStep(1); QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed); if (q->orientation() == Qt::Vertical) diff --git a/components/sliderthumb.cpp b/components/sliderthumb.cpp index 5f68a16..65a3b18 100644 --- a/components/sliderthumb.cpp +++ b/components/sliderthumb.cpp @@ -1,6 +1,7 @@ #include "sliderthumb.h" #include #include +#include #include "lib/style.h" #include "slider.h" @@ -24,8 +25,15 @@ SliderThumb::~SliderThumb() bool SliderThumb::eventFilter(QObject *obj, QEvent *event) { - if (QEvent::ParentChange == event->type()) { + QEvent::Type type = event->type(); + + if (QEvent::ParentChange == type) { setParent(slider->parentWidget()); + } else if (QEvent::Resize == type || QEvent::Move == type) { + QWidget *widget; + if ((widget = parentWidget())) { + setGeometry(widget->rect()); + } } return QWidget::eventFilter(obj, event); } @@ -45,10 +53,8 @@ void SliderThumb::paintEvent(QPaintEvent *event) painter.setRenderHint(QPainter::Antialiasing); QPointF disp = Qt::Horizontal == slider->orientation() - ? QPointF(SLIDER_MARGIN + slider->thumbOffset(), - slider->height()/2) - : QPointF(slider->width()/2, - SLIDER_MARGIN + slider->thumbOffset()); + ? QPointF(SLIDER_MARGIN + slider->thumbOffset(), slider->height()/2) + : QPointF(slider->width()/2, SLIDER_MARGIN + slider->thumbOffset()); QRectF halo((slider->pos() - QPointF(_haloSize, _haloSize)/2) + disp, QSizeF(_haloSize, _haloSize)); @@ -57,9 +63,9 @@ void SliderThumb::paintEvent(QPaintEvent *event) // Knob - brush.setStyle(Qt::SolidPattern); brush.setColor(slider->value() > slider->minimum() - ? (slider->isEnabled() ? _fillColor : Style::instance().themeColor("disabled")) + ? (slider->isEnabled() + ? _fillColor : Style::instance().themeColor("disabled")) : _minFillColor); painter.setBrush(brush); diff --git a/components/slidertrack.cpp b/components/slidertrack.cpp index 4ffea52..42631a9 100644 --- a/components/slidertrack.cpp +++ b/components/slidertrack.cpp @@ -11,6 +11,8 @@ SliderTrack::SliderTrack(Slider *slider) { slider->installEventFilter(this); setAttribute(Qt::WA_TransparentForMouseEvents, true); + + connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(update())); } SliderTrack::~SliderTrack() @@ -19,8 +21,14 @@ SliderTrack::~SliderTrack() bool SliderTrack::eventFilter(QObject *obj, QEvent *event) { - if (QEvent::ParentChange == event->type()) { + QEvent::Type type = event->type(); + + if (QEvent::ParentChange == type) { setParent(slider->parentWidget()); + } else if (QEvent::Resize == type || QEvent::Move == type) { + if (parentWidget()) { + setGeometry(parentWidget()->rect()); + } } return QWidget::eventFilter(obj, event); } @@ -36,44 +44,49 @@ void SliderTrack::paintEvent(QPaintEvent *event) : style.themeColor("disabled")); QBrush bg; bg.setStyle(Qt::SolidPattern); - bg.setColor(slider->isEnabled() ? _fillColor : style.themeColor("disabled")); + bg.setColor(slider->isEnabled() ? _fillColor + : style.themeColor("disabled")); + + painter.setRenderHint(QPainter::Antialiasing); qreal offset = slider->thumbOffset(); - QSizeF box(slider->isEnabled() ? offset : offset - 7, - qMax(slider->width(), slider->height())); - - if (Qt::Vertical == slider->orientation()) - box.transpose(); - - QRectF rect = Qt::Vertical == slider->orientation() - ? QRectF(0, slider->isEnabled() ? slider->y() + offset + SLIDER_MARGIN - : slider->y() + offset + SLIDER_MARGIN + 7, - box.width(), box.width()) - : QRectF(slider->isEnabled() ? slider->x() + offset + SLIDER_MARGIN - : slider->x() + offset + SLIDER_MARGIN + 7, 0, - box.height(), box.height()); - - qreal hw = static_cast(_width)/2; + if (Qt::Horizontal == slider->orientation()) { + painter.translate(slider->x() + SLIDER_MARGIN, + slider->y() + slider->height()/2 + - static_cast(_width)/2); + } else { + painter.translate(slider->x() + slider->width()/2 + - static_cast(_width)/2, + slider->y() + SLIDER_MARGIN); + } QRectF geometry = Qt::Horizontal == slider->orientation() - ? QRectF(slider->x() + SLIDER_MARGIN, - slider->y() + slider->height()/2 - hw, - slider->width() - SLIDER_MARGIN*2, - hw*2) - : QRectF(slider->x() + slider->width()/2 - hw, - slider->y() + SLIDER_MARGIN, - hw*2, - slider->height() - SLIDER_MARGIN*2); + ? QRectF(0, 0, slider->width() - SLIDER_MARGIN*2, _width) + : QRectF(0, 0, _width, slider->height() - SLIDER_MARGIN*2); - bool inverted = slider->invertedAppearance(); + QRectF bgRect; + QRectF fgRect; - QPointF pos = Qt::Horizontal == slider->orientation() - ? QPointF(slider->x() + SLIDER_MARGIN, 0) - : QPointF(0, slider->y() + SLIDER_MARGIN); + if (Qt::Horizontal == slider->orientation()) { + fgRect = QRectF(0, 0, offset, _width); + bgRect = QRectF(offset, 0, slider->width(), _width).intersected(geometry); + } else { + fgRect = QRectF(0, 0, _width, offset); + bgRect = QRectF(0, offset, _width, slider->height()).intersected(geometry); + } - painter.fillRect(QRectF(pos, box).intersected(geometry), inverted ? bg : fg); - painter.fillRect(rect.intersected(geometry), inverted ? fg : bg); + if (!slider->isEnabled()) { + fgRect = fgRect.width() < 9 ? QRectF() : fgRect.adjusted(0, 0, -6, 0); + bgRect = bgRect.width() < 9 ? QRectF() : bgRect.adjusted(6, 0, 0, 0); + } + + if (slider->invertedAppearance()) { + qSwap(bgRect, fgRect); + } + + painter.fillRect(bgRect, bg); + painter.fillRect(fgRect, fg); #ifdef DEBUG_LAYOUT if (slider->hovered()) {