12#include <QStyleOptionSlider> 
   13#include <QApplication> 
   14#include <QStylePainter> 
   18#include "ctk3slider.h" 
   20class ctk3SliderPrivate
 
   22        Q_DECLARE_PUBLIC(ctk3Slider)
 
   24        ctk3Slider* 
const q_ptr;
 
   35        Q_DECLARE_FLAGS(Handles, Handle)
 
   37        ctk3SliderPrivate(ctk3Slider &
object);
 
   44        Handle handleAtPos(
const QPoint &pos, QRect &handleRect)
const;
 
   47        int pixelPosToRangeValue(
int pos) 
const;
 
   48        int pixelPosFromRangeValue(
int val) 
const;
 
   51        void drawMinimumSlider( QStylePainter* painter ) 
const;
 
   52        void drawMaximumSlider( QStylePainter* painter ) 
const;
 
   53        void drawMidSlider( QStylePainter* painter ) 
const;
 
   61        int m_MaximumPosition;
 
   62        int m_MinimumPosition;
 
   72        int m_SubclassClickOffset;
 
   76        int m_SubclassPosition;
 
   81        ctk3SliderPrivate::Handles m_SelectedHandles;
 
   83        QString m_HandleToolTip;
 
   86        Q_DISABLE_COPY(ctk3SliderPrivate)
 
   90ctk3SliderPrivate::ctk3SliderPrivate(
ctk3Slider &
object)
 
   93    this->m_MinimumValue = 0;
 
   94    this->m_MaximumValue = 100;
 
   95    this->m_MidValue = 50;
 
   96    this->m_MinimumPosition = 0;
 
   97    this->m_MaximumPosition = 100;
 
   98    this->m_MidPosition = 50;
 
  102    this->m_SubclassClickOffset = 0;
 
  103    this->m_SubclassPosition = 0;
 
  104    this->m_SubclassWidth = 0;
 
  105    this->m_SelectedHandles = ctk3SliderPrivate::NoHandle;
 
  109void ctk3SliderPrivate::init()
 
  112    this->m_MinimumValue = q->minimum();
 
  113    this->m_MaximumValue = q->maximum();
 
  114    this->m_MaximumValue = (q->minimum() + q->maximum()) / 2.0;
 
  115    this->m_MinimumPosition = q->minimum();
 
  116    this->m_MaximumPosition = q->maximum();
 
  117    this->m_MidPosition = (q->minimum() + q->maximum()) / 2.0;
 
  118    q->connect(q, SIGNAL(rangeChanged(
int, 
int)), q, SLOT(onRangeChanged(
int, 
int)));
 
  122ctk3SliderPrivate::Handle ctk3SliderPrivate::handleAtPos(
const QPoint &pos, 
QRect &handleRect)
const 
  124    Q_Q(
const ctk3Slider);
 
  126    QStyleOptionSlider option;
 
  127    q->initStyleOption( &option );
 
  134    option.sliderPosition = this->m_MinimumPosition;
 
  135    option.sliderValue    = this->m_MinimumValue;
 
  139    QRect minimumHandleRect = q->style()->subControlRect(
 
  143    option.sliderPosition = this->m_MaximumPosition;
 
  144    option.sliderValue    = this->m_MaximumValue;
 
  148    QRect maximumHandleRect = q->style()->subControlRect(
 
  152    option.sliderPosition = this->m_MidPosition;
 
  153    option.sliderValue    = this->m_MidValue;
 
  157    QRect midHandleRect = q->style()->subControlRect(
 
  162        handleRect = minimumHandleRect;
 
  163        return MinimumHandle;
 
  167        handleRect = midHandleRect;
 
  172        handleRect = maximumHandleRect;
 
  173        return MaximumHandle;
 
  175    handleRect = minimumHandleRect.
united(maximumHandleRect);
 
  182int ctk3SliderPrivate::pixelPosToRangeValue( 
int pos )
 const 
  184    Q_Q(
const ctk3Slider);
 
  185    QStyleOptionSlider option;
 
  186    q->initStyleOption( &option );
 
  196    int sliderMin, sliderMax, sliderLength;
 
  199        sliderLength = sr.
width();
 
  201        sliderMax = gr.
right() - sliderLength + 1;
 
  205        sliderLength = sr.
height();
 
  207        sliderMax = gr.
bottom() - sliderLength + 1;
 
  213                                            sliderMax - sliderMin,
 
  218int ctk3SliderPrivate::pixelPosFromRangeValue( 
int val )
 const 
  220    Q_Q(
const ctk3Slider);
 
  221    QStyleOptionSlider option;
 
  222    q->initStyleOption( &option );
 
  232    int sliderMin, sliderMax, sliderLength;
 
  235        sliderLength = sr.
width();
 
  237        sliderMax = gr.
right() - sliderLength + 1;
 
  241        sliderLength = sr.
height();
 
  243        sliderMax = gr.
bottom() - sliderLength + 1;
 
  249                                            sliderMax - sliderMin,
 
  250                                            option.upsideDown ) + sliderMin;
 
  255void ctk3SliderPrivate::drawMinimumSlider( 
QStylePainter* painter )
 const 
  257    Q_Q(
const ctk3Slider);
 
  258    QStyleOptionSlider option;
 
  259    q->initMinimumSliderStyleOption( &option );
 
  262    option.sliderValue = m_MinimumValue;
 
  263    option.sliderPosition = m_MinimumPosition;
 
  264    if (q->isMinimumSliderDown())
 
  280void ctk3SliderPrivate::drawMaximumSlider( 
QStylePainter* painter )
 const 
  282    Q_Q(
const ctk3Slider);
 
  283    QStyleOptionSlider option;
 
  284    q->initMaximumSliderStyleOption( &option );
 
  287    option.sliderValue = m_MaximumValue;
 
  288    option.sliderPosition = m_MaximumPosition;
 
  289    if (q->isMaximumSliderDown())
 
  304void ctk3SliderPrivate::drawMidSlider( 
QStylePainter* painter )
 const 
  306    Q_Q(
const ctk3Slider);
 
  307    QStyleOptionSlider option;
 
  308    q->initMidSliderStyleOption( &option );
 
  311    option.sliderValue = m_MidValue;
 
  312    option.sliderPosition = m_MidPosition;
 
  313    if (q->isMidSliderDown())
 
  330    , d_ptr(new ctk3SliderPrivate(*this))
 
  340    , d_ptr(new ctk3SliderPrivate(*this))
 
 
  366ctk3Slider::~ctk3Slider()
 
  371int ctk3Slider::minimumValue()
 const 
  374    return d->m_MinimumValue;
 
 
  382    int newMin = qMin( qMin(min, d->m_MidValue), d->m_MaximumValue);
 
  383    this->
setValues( newMin, d->m_MidValue, d->m_MaximumValue);
 
 
  387int ctk3Slider::maximumValue()
 const 
  390    return d->m_MaximumValue;
 
 
  398    int newMax = qMax( qMax(max, d->m_MidValue), d->m_MinimumValue);
 
  399    this->
setValues(d->m_MinimumValue, d->m_MidValue, newMax);
 
 
  403int ctk3Slider::midValue()
 const 
  406    return d->m_MidValue;
 
 
  414    int newMid = qMax(d->m_MinimumValue, mid);
 
  415    newMid = qMin(newMid, d->m_MaximumValue);
 
  416    this->
setValues(d->m_MinimumValue, newMid, d->m_MaximumValue);
 
 
  423void sortLMU(
int &l, 
int &m, 
int &u)
 
  425    int kL = l, kM = m, kU = u;
 
  426    if (l <= m && l <= u) 
 
  437    else if (m <= l && m <= u) 
 
  481    bool emitMinValChanged = (minValue != d->m_MinimumValue);
 
  482    bool emitMaxValChanged = (maxValue != d->m_MaximumValue);
 
  483    bool emitMidValChanged = (midValue != d->m_MidValue);
 
  485    d->m_MinimumValue = minValue;
 
  486    d->m_MaximumValue = maxValue;
 
  487    d->m_MidValue = midValue;
 
  489    bool emitMinPosChanged =
 
  490        (minValue != d->m_MinimumPosition);
 
  491    bool emitMaxPosChanged =
 
  492        (maxValue != d->m_MaximumPosition);
 
  493    bool emitMidPosChanged =
 
  494        (midValue != d->m_MidPosition);
 
  495    d->m_MinimumPosition = minValue;
 
  496    d->m_MaximumPosition = maxValue;
 
  497    d->m_MidPosition = midValue;
 
  501        if (emitMinPosChanged || emitMaxPosChanged || emitMidPosChanged)
 
  503            emit 
positionsChanged(d->m_MinimumPosition, d->m_MidPosition, d->m_MaximumPosition);
 
  505        if (emitMinPosChanged)
 
  509        if (emitMaxPosChanged)
 
  513        if (emitMidPosChanged)
 
  518    if (emitMinValChanged || emitMaxValChanged || emitMidValChanged)
 
  520        emit 
valuesChanged(d->m_MinimumValue, d->m_MidValue, d->m_MaximumValue);
 
  522    if (emitMinValChanged)
 
  526    if (emitMaxValChanged)
 
  530    if (emitMidValChanged)
 
  534    if (emitMinPosChanged || emitMaxPosChanged || emitMidPosChanged ||
 
  535            emitMinValChanged || emitMaxValChanged || emitMidValChanged)
 
 
  542int ctk3Slider::minimumPosition()
 const 
  545    return d->m_MinimumPosition;
 
 
  549int ctk3Slider::maximumPosition()
 const 
  552    return d->m_MaximumPosition;
 
 
  555int ctk3Slider::midPosition()
 const 
  558    return d->m_MidPosition;
 
 
  562void ctk3Slider::setMinimumPosition(
int l)
 
  566    int newMin = qMin( qMin(l, d->m_MidPosition), d->m_MaximumPosition);
 
  567    this->
setPositions(newMin, d->m_MidPosition, d->m_MaximumPosition);
 
  571void ctk3Slider::setMaximumPosition(
int u)
 
  575    int newMax = qMax( qMax(u, d->m_MidPosition), d->m_MinimumPosition);
 
  576    this->
setPositions(d->m_MinimumPosition, d->m_MidPosition, newMax);
 
  579void ctk3Slider::setMidPosition(
int m)
 
  583    int newMid = qMax(d->m_MinimumPosition, m);
 
  584    newMid = qMin(newMid, d->m_MaximumPosition);
 
  585    this->
setPositions(d->m_MinimumPosition, newMid, d->m_MaximumPosition);
 
  592    sortLMU(min, mid, max);
 
  593    const int minPosition =
 
  595    const int maxPosition =
 
  597    const int midPosition =
 
  600    bool emitMinPosChanged = (minPosition != d->m_MinimumPosition);
 
  601    bool emitMaxPosChanged = (maxPosition != d->m_MaximumPosition);
 
  602    bool emitMidPosChanged = (midPosition != d->m_MidPosition);
 
  604    if (!emitMinPosChanged && !emitMaxPosChanged && !emitMidPosChanged)
 
  609    d->m_MinimumPosition = minPosition;
 
  610    d->m_MaximumPosition = maxPosition;
 
  611    d->m_MidPosition = midPosition;
 
  619        if (emitMinPosChanged)
 
  623        if (emitMaxPosChanged)
 
  627        if (emitMidPosChanged)
 
  631        if (emitMinPosChanged || emitMaxPosChanged || emitMidPosChanged)
 
  633            emit 
positionsChanged(d->m_MinimumPosition, d->m_MidPosition, d->m_MaximumPosition);
 
  639        this->
setValues(d->m_MinimumPosition, d->m_MidPosition, d->m_MaximumPosition);
 
 
  644void ctk3Slider::onRangeChanged(
int _minimum, 
int _maximum)
 
  649    this->
setValues(d->m_MinimumValue, d->m_MidValue, d->m_MaximumValue);
 
  657    QStyleOptionSlider option;
 
  660    QStylePainter painter(
this);
 
  669    option.sliderPosition = d->m_MinimumPosition;
 
  675    option.sliderPosition = d->m_MidPosition;
 
  682    option.sliderPosition = d->m_MaximumPosition;
 
  714    groove.
adjust(0, 0, -1, 0);
 
  719    QLinearGradient gradient;
 
  722        gradient = QLinearGradient( groove.
center().
x(), groove.
top(),
 
  727        gradient = QLinearGradient( groove.
left(), groove.
center().
y(),
 
  743        d->drawMaximumSlider( &painter );
 
  744        d->drawMidSlider( &painter );
 
  745        d->drawMinimumSlider( &painter );
 
  749        d->drawMaximumSlider( &painter );
 
  750        d->drawMinimumSlider( &painter );
 
  751        d->drawMidSlider( &painter );
 
  755        d->drawMinimumSlider( &painter );
 
  756        d->drawMidSlider( &painter );
 
  757        d->drawMaximumSlider( &painter );
 
  763void ctk3Slider::mousePressEvent(
QMouseEvent* mouseEvent)
 
  772                mouseEvent->
pos().
x() : mouseEvent->
pos().
y();
 
  774    QStyleOptionSlider option;
 
  778    ctk3SliderPrivate::Handle handle_ = d->handleAtPos(mouseEvent->
pos(), handleRect);
 
  780    if (handle_ != ctk3SliderPrivate::NoHandle)
 
  782        if (handle_ == ctk3SliderPrivate::MinimumHandle)
 
  783            d->m_SubclassPosition = d->m_MinimumPosition;
 
  784        else if (handle_ == ctk3SliderPrivate::MaximumHandle)
 
  785            d->m_SubclassPosition = d->m_MaximumPosition;
 
  786        else if (handle_ == ctk3SliderPrivate::MidHandle)
 
  787            d->m_SubclassPosition = d->m_MidPosition;
 
  791                                            handleRect.
left() : handleRect.
top());
 
  795        if (d->m_SelectedHandles != handle_)
 
  797            d->m_SelectedHandles = handle_;
 
  813                     handleRect.
left() : handleRect.
top());
 
  817            mepos > minCenter && mepos < maxCenter)
 
  820        d->m_SubclassPosition = (d->m_MinimumPosition + d->m_MaximumPosition) / 2.;
 
  821        d->m_SubclassClickOffset = mepos - d->pixelPosFromRangeValue(d->m_SubclassPosition);
 
  822        d->m_SubclassWidth = (d->m_MaximumPosition - d->m_MinimumPosition) / 2;
 
  823        qMax(d->m_SubclassPosition - d->m_MinimumPosition, d->m_MaximumPosition - d->m_SubclassPosition);
 
  827            d->m_SelectedHandles =
 
  828                QFlags<ctk3SliderPrivate::Handle>(ctk3SliderPrivate::MinimumHandle) |
 
  829                QFlags<ctk3SliderPrivate::Handle>(ctk3SliderPrivate::MaximumHandle);
 
  840void ctk3Slider::mouseMoveEvent(
QMouseEvent* mouseEvent)
 
  843    if (!d->m_SelectedHandles)
 
  849                mouseEvent->
pos().
x() : mouseEvent->
pos().
y();
 
  851    QStyleOptionSlider option;
 
  856    int newPosition = d->pixelPosToRangeValue(mepos - d->m_SubclassClickOffset);
 
  860        const QRect r = 
rect().adjusted(-m, -m, m, m);
 
  863            newPosition = d->m_SubclassPosition;
 
  873        if (newPosition < d->m_MidPosition)
 
  874            this->
setPositions(newPosition, d->m_MidPosition, d->m_MaximumPosition);
 
  876            this->
setPositions(d->m_MinimumPosition, newPosition, d->m_MaximumPosition);
 
  882        if (newPosition < d->m_MaximumPosition)
 
  883            this->
setPositions(d->m_MinimumPosition, newPosition, d->m_MaximumPosition);
 
  885            this->
setPositions(d->m_MinimumPosition, d->m_MidPosition, newPosition);
 
  889        double newMinPos = qMin(newPosition, d->m_MidPosition);
 
  890        this->
setPositions(newMinPos, d->m_MidPosition, d->m_MaximumPosition);
 
  895        double newMaxPos = qMax(d->m_MidPosition, newPosition);
 
  896        this->
setPositions(d->m_MinimumPosition, d->m_MidPosition, newMaxPos);
 
  901        double newMidPos = qMin(qMax(d->m_MinimumPosition, newPosition), d->m_MaximumPosition);
 
  902        this->
setPositions(d->m_MinimumPosition, newMidPos, d->m_MaximumPosition);
 
  909void ctk3Slider::mouseReleaseEvent(
QMouseEvent* mouseEvent)
 
  915    d->m_SelectedHandles = ctk3SliderPrivate::NoHandle;
 
  917    emit released(d->m_MinimumValue, d->m_MidValue, d->m_MaximumValue);
 
  925    return d->m_SelectedHandles & ctk3SliderPrivate::MinimumHandle;
 
 
  932    return d->m_SelectedHandles & ctk3SliderPrivate::MaximumHandle;
 
 
  938    return d->m_SelectedHandles & ctk3SliderPrivate::MidHandle;
 
 
  962    return d->m_HandleToolTip;
 
 
  966void ctk3Slider::setHandleToolTip(
const QString &_toolTip)
 
  969    d->m_HandleToolTip = _toolTip;
 
  973bool ctk3Slider::event(
QEvent* _event)
 
  976    switch(_event->
type())
 
  980            QHelpEvent* helpEvent = 
static_cast<QHelpEvent*
>(_event);
 
  981            QStyleOptionSlider opt;
 
  983            opt.sliderPosition = d->m_MinimumPosition;
 
  984            opt.sliderValue = d->m_MinimumValue;
 
  989            if (!d->m_HandleToolTip.isEmpty() &&
 
  997            opt.sliderPosition = d->m_MaximumPosition;
 
  998            opt.sliderValue = d->m_MaximumValue;
 
 1002            if (!d->m_HandleToolTip.isEmpty() &&
 
 1010            opt.sliderPosition = d->m_MidPosition;
 
 1011            opt.sliderValue = d->m_MidValue;
 
 1015            if (!d->m_HandleToolTip.isEmpty() &&
 
A ctk3Slider is a slider that lets you input 2 values instead of one (see QSlider).
 
void maximumPositionChanged(int max)
This signal is emitted when sliderDown is true and the slider moves.
 
void setValues(int min, int mid, int max)
Utility function that set the minimum value and maximum value at once.
 
void setMaximumValue(int max)
This property holds the slider's current maximum value.
 
void minimumPositionChanged(int min)
This signal is emitted when sliderDown is true and the slider moves.
 
void maximumValueChanged(int max)
This signal is emitted when the slider maximum value has changed, with the new slider value as argume...
 
void minimumValueChanged(int min)
This signal is emitted when the slider minimum value has changed, with the new slider value as argume...
 
void positionsChanged(int min, int mid, int max)
Utility signal that is fired when minimum or maximum positions have changed.
 
bool isMaximumSliderDown() const
Returns true if the maximum value handle is down, false if it is up.
 
void setPositions(int min, int mid, int max)
Utility function that set the minimum, mid and maximum position at once.
 
ctk3Slider(Qt::Orientation o, QWidget *par=0)
Constructor, builds a ctk3Slider that ranges from 0 to 100 and has a lower and upper values of 0 and ...
 
void setMinimumValue(int min)
This property holds the slider's current minimum value.
 
void setMidValue(int mid)
This property holds the slider's current mid value.
 
bool isMidSliderDown() const
Returns true if the mid value handle is down, false if it is up.
 
void midValueChanged(int mid)
This signal is emitted when the slider mid value has changed, with the new slider value as argument.
 
void midPositionChanged(int max)
This signal is emitted when sliderDown is true and the slider moves.
 
void valuesChanged(int min, int mid, int max)
Utility signal that is fired when minimum, mid or maximum values have changed.
 
bool isMinimumSliderDown() const
Returns true if the minimum value handle is down, false if it is up.
 
bool isSliderDown() const const
 
bool hasTracking() const const
 
void triggerAction(SliderAction action)
 
QColor darker(int factor) const const
 
QColor lighter(int factor) const const
 
void setColorAt(qreal position, const QColor &color)
 
const QPoint & globalPos() const const
 
const QPoint & pos() const const
 
void drawRect(const QRect &rectangle)
 
void setBrush(Qt::BrushStyle style)
 
void setClipRect(const QRect &rectangle, Qt::ClipOperation operation)
 
void setPen(Qt::PenStyle style)
 
void adjust(int dx1, int dy1, int dx2, int dy2)
 
QPoint center() const const
 
bool contains(const QPoint &point, bool proper) const const
 
QRect intersected(const QRect &rectangle) const const
 
QRect united(const QRect &rectangle) const const
 
virtual bool event(QEvent *event) override
 
virtual void initStyleOption(QStyleOptionSlider *option) const const
 
virtual void mouseReleaseEvent(QMouseEvent *ev) override
 
virtual SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &position, const QWidget *widget) const const=0
 
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const const=0
 
int sliderPositionFromValue(int min, int max, int logicalValue, int span, bool upsideDown)
 
int sliderValueFromPosition(int min, int max, int position, int span, bool upsideDown)
 
virtual QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const const=0
 
void drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex &option)
 
void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecDisplayTime)