| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 | /*=========================================================================  Library:   CTK  Copyright (c) Kitware Inc.   All rights reserved.  Distributed under a BSD License. See LICENSE.txt file.  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the above copyright notice for more information.=========================================================================*/// QT includes#include <QDebug>#include <QHBoxLayout>// CTK includes#include "ctkDoubleSlider.h"// STD includes#include <limits>//-----------------------------------------------------------------------------class ctkDoubleSliderPrivate: public ctkPrivate<ctkDoubleSlider>{  public:  ctkDoubleSliderPrivate();  int toInt(double _value)const;  double fromInt(int _value)const;  void init();  void updateOffset(double value);  QSlider*    Slider;  double      Minimum;  double      Maximum;  // we should have a Offset and SliderPositionOffset (and MinimumOffset?)  double      Offset;  double      SingleStep;  double      Value;};// --------------------------------------------------------------------------ctkDoubleSliderPrivate::ctkDoubleSliderPrivate(){  this->Slider = 0;  this->Minimum = 0.;  this->Maximum = 100.;  this->Offset = 0.;  this->SingleStep = 1.;  this->Value = 0.;}// --------------------------------------------------------------------------void ctkDoubleSliderPrivate::init(){  CTK_P(ctkDoubleSlider);  this->Slider = new QSlider(p);  QHBoxLayout* l = new QHBoxLayout(p);  l->addWidget(this->Slider);  l->setContentsMargins(0,0,0,0);    this->Minimum = this->Slider->minimum();  this->Maximum = this->Slider->maximum();  this->SingleStep = this->Slider->singleStep();  this->Value = this->Slider->value();  p->connect(this->Slider, SIGNAL(valueChanged(int)), p, SLOT(onValueChanged(int)));  p->connect(this->Slider, SIGNAL(sliderMoved(int)), p, SLOT(onSliderMoved(int)));  p->connect(this->Slider, SIGNAL(sliderPressed()), p, SIGNAL(sliderPressed()));  p->connect(this->Slider, SIGNAL(sliderReleased()), p, SIGNAL(sliderReleased()));}  // --------------------------------------------------------------------------int ctkDoubleSliderPrivate::toInt(double doubleValue)const{  double tmp = doubleValue / this->SingleStep;  static const double minInt = std::numeric_limits<int>::min();  static const double maxInt = std::numeric_limits<int>::max();#ifndef QT_NO_DEBUG  if (tmp < minInt || tmp > maxInt)    {    qWarning("ctkDoubleSliderPrivate::toInt value out of bounds !");    }#endif  tmp = qBound(minInt, tmp, maxInt);  int intValue = qRound(tmp);  //qDebug() << __FUNCTION__ << doubleValue << tmp << intValue;  return intValue;}// --------------------------------------------------------------------------double ctkDoubleSliderPrivate::fromInt(int intValue)const{  double doubleValue = this->SingleStep * (this->Offset + intValue) ;  //qDebug() << __FUNCTION__ << intValue << doubleValue;  return doubleValue;}// --------------------------------------------------------------------------void ctkDoubleSliderPrivate::updateOffset(double value){  this->Offset = (value / this->SingleStep) - this->toInt(value);}// --------------------------------------------------------------------------ctkDoubleSlider::ctkDoubleSlider(QWidget* _parent) : Superclass(_parent){  CTK_INIT_PRIVATE(ctkDoubleSlider);  ctk_d()->init();}// --------------------------------------------------------------------------ctkDoubleSlider::ctkDoubleSlider(Qt::Orientation _orientation, QWidget* _parent)  : Superclass(_parent){  CTK_INIT_PRIVATE(ctkDoubleSlider);  ctk_d()->init();  this->setOrientation(_orientation);}// --------------------------------------------------------------------------ctkDoubleSlider::~ctkDoubleSlider(){}// --------------------------------------------------------------------------void ctkDoubleSlider::setMinimum(double min){  CTK_D(ctkDoubleSlider);  d->Minimum = min;  if (d->Minimum >= d->Value)    {    d->updateOffset(d->Minimum);    }  d->Slider->setMinimum(d->toInt(min));}// --------------------------------------------------------------------------void ctkDoubleSlider::setMaximum(double max){  CTK_D(ctkDoubleSlider);  d->Maximum = max;  if (d->Maximum <= d->Value)    {    d->updateOffset(d->Maximum);    }  d->Slider->setMaximum(d->toInt(max));}// --------------------------------------------------------------------------void ctkDoubleSlider::setRange(double min, double max){  CTK_D(ctkDoubleSlider);  d->Minimum = min;  d->Maximum = max;    if (d->Minimum >= d->Value)    {    d->updateOffset(d->Minimum);    }  if (d->Maximum <= d->Value)    {    d->updateOffset(d->Maximum);    }    d->Slider->setRange(d->toInt(min), d->toInt(max));}// --------------------------------------------------------------------------double ctkDoubleSlider::minimum()const{  CTK_D(const ctkDoubleSlider);  return d->Minimum;}// --------------------------------------------------------------------------double ctkDoubleSlider::maximum()const{  CTK_D(const ctkDoubleSlider);  return d->Maximum;}// --------------------------------------------------------------------------double ctkDoubleSlider::sliderPosition()const{  CTK_D(const ctkDoubleSlider);  return d->fromInt(d->Slider->sliderPosition());}// --------------------------------------------------------------------------void ctkDoubleSlider::setSliderPosition(double newSliderPosition){  CTK_D(ctkDoubleSlider);  d->Slider->setSliderPosition(d->toInt(newSliderPosition));}// --------------------------------------------------------------------------double ctkDoubleSlider::value()const{  CTK_D(const ctkDoubleSlider);  return d->Value;}// --------------------------------------------------------------------------void ctkDoubleSlider::setValue(double newValue){  CTK_D(ctkDoubleSlider);  newValue = qBound(d->Minimum, newValue, d->Maximum);  d->updateOffset(newValue);  int newIntValue = d->toInt(newValue);  if (newIntValue != d->Slider->value())    {    // d->Slider will emit a valueChanged signal that is connected to    // ctkDoubleSlider::onValueChanged    d->Slider->setValue(newIntValue);    }  else    {    double oldValue = d->Value;    d->Value = newValue;    // don't emit a valuechanged signal if the new value is quite     // similar to the old value.    if (qAbs(newValue - oldValue) > (d->SingleStep * 0.000000001))      {      emit this->valueChanged(newValue);      }    }}// --------------------------------------------------------------------------double ctkDoubleSlider::singleStep()const{  CTK_D(const ctkDoubleSlider);  return d->SingleStep;}// --------------------------------------------------------------------------void ctkDoubleSlider::setSingleStep(double newStep){  CTK_D(ctkDoubleSlider);  d->SingleStep = newStep;  // update the new values of the QSlider  double _value = d->Value;  d->updateOffset(_value);  bool oldBlockSignals = this->blockSignals(true);  this->setRange(d->Minimum, d->Maximum);  d->Slider->setValue(d->toInt(_value));  d->Value = _value;  this->blockSignals(oldBlockSignals);}// --------------------------------------------------------------------------double ctkDoubleSlider::tickInterval()const{  CTK_D(const ctkDoubleSlider);  return d->fromInt(d->Slider->tickInterval());}// --------------------------------------------------------------------------void ctkDoubleSlider::setTickInterval(double newTickInterval){  CTK_D(ctkDoubleSlider);  d->Slider->setTickInterval(d->toInt(newTickInterval));}// --------------------------------------------------------------------------bool ctkDoubleSlider::hasTracking()const{  CTK_D(const ctkDoubleSlider);  return d->Slider->hasTracking();}// --------------------------------------------------------------------------void ctkDoubleSlider::setTracking(bool enable){  CTK_D(ctkDoubleSlider);  d->Slider->setTracking(enable);}// --------------------------------------------------------------------------void ctkDoubleSlider::triggerAction( QAbstractSlider::SliderAction action){  CTK_D(ctkDoubleSlider);  d->Slider->triggerAction(action);}// --------------------------------------------------------------------------Qt::Orientation ctkDoubleSlider::orientation()const{  CTK_D(const ctkDoubleSlider);  return d->Slider->orientation();}// --------------------------------------------------------------------------void ctkDoubleSlider::setOrientation(Qt::Orientation newOrientation){  CTK_D(ctkDoubleSlider);  d->Slider->setOrientation(newOrientation);}// --------------------------------------------------------------------------void ctkDoubleSlider::onValueChanged(int newValue){  CTK_D(ctkDoubleSlider);  double doubleNewValue = d->fromInt(newValue);/*  qDebug() << "onValueChanged: " << newValue << "->"<< d->fromInt(newValue+d->Offset)            << " old: " << d->Value << "->" << d->toInt(d->Value)            << "offset:" << d->Offset << doubleNewValue;*/  if (d->Value == doubleNewValue)    {    return;    }  d->Value = doubleNewValue;  emit this->valueChanged(d->Value);}// --------------------------------------------------------------------------void ctkDoubleSlider::onSliderMoved(int newPosition){  CTK_D(const ctkDoubleSlider);  emit this->sliderMoved(d->fromInt(newPosition));}
 |