Browse Source

ENH: Support custom sliders in ctkDoubleRangeSlider and ctkRangeWidget

The sliders internally used by ctkDoubleRangeSlider and ctkRangeWidget can
now be custom sliders.
ctkRangeSlider now supports a way to control the QStyleOptions of the
handles (min and max) drawings
Julien Finet 14 years ago
parent
commit
c64f7c0450

+ 49 - 8
Libs/Widgets/ctkDoubleRangeSlider.cpp

@@ -37,6 +37,7 @@ public:
   double minFromInt(int _value)const;
   double maxFromInt(int _value)const;
   void init();
+  void connectSlider();
   void updateMinOffset(double value);
   void updateMaxOffset(double value);
 
@@ -80,16 +81,31 @@ void ctkDoubleRangeSliderPrivate::init()
   this->MaxValue = this->Slider->maximumValue();
   this->SingleStep = this->Slider->singleStep();
 
-  p->connect(this->Slider, SIGNAL(minimumValueChanged(int)), p, SLOT(onMinValueChanged(int)));
-  p->connect(this->Slider, SIGNAL(maximumValueChanged(int)), p, SLOT(onMaxValueChanged(int)));
-  p->connect(this->Slider, SIGNAL(valuesChanged(int,int)), p, SLOT(onValuesChanged(int,int)));
+  this->connectSlider();
+}
+
+// --------------------------------------------------------------------------
+void ctkDoubleRangeSliderPrivate::connectSlider()
+{
+  CTK_P(ctkDoubleRangeSlider);
+  p->connect(this->Slider, SIGNAL(minimumValueChanged(int)),
+             p, SLOT(onMinValueChanged(int)));
+  p->connect(this->Slider, SIGNAL(maximumValueChanged(int)),
+             p, SLOT(onMaxValueChanged(int)));
+  p->connect(this->Slider, SIGNAL(valuesChanged(int,int)),
+             p, SLOT(onValuesChanged(int,int)));
 
-  p->connect(this->Slider, SIGNAL(minimumPositionChanged(int)), p, SLOT(onMinPosChanged(int)));
-  p->connect(this->Slider, SIGNAL(maximumPositionChanged(int)), p, SLOT(onMaxPosChanged(int)));
-  p->connect(this->Slider, SIGNAL(positionsChanged(int,int)), p, SLOT(onPositionsChanged(int,int)));
+  p->connect(this->Slider, SIGNAL(minimumPositionChanged(int)),
+             p, SLOT(onMinPosChanged(int)));
+  p->connect(this->Slider, SIGNAL(maximumPositionChanged(int)),
+             p, SLOT(onMaxPosChanged(int)));
+  p->connect(this->Slider, SIGNAL(positionsChanged(int,int)),
+             p, SLOT(onPositionsChanged(int,int)));
 
-  p->connect(this->Slider, SIGNAL(sliderPressed()), p, SIGNAL(sliderPressed()));
-  p->connect(this->Slider, SIGNAL(sliderReleased()), p, SIGNAL(sliderReleased()));
+  p->connect(this->Slider, SIGNAL(sliderPressed()),
+             p, SIGNAL(sliderPressed()));
+  p->connect(this->Slider, SIGNAL(sliderReleased()),
+             p, SIGNAL(sliderReleased()));
 }
 
 // --------------------------------------------------------------------------
@@ -477,9 +493,34 @@ void ctkDoubleRangeSlider::onMaxPosChanged(int newPosition)
   CTK_D(const ctkDoubleRangeSlider);
   emit this->maximumPositionChanged(d->maxFromInt(newPosition));
 }
+
 // --------------------------------------------------------------------------
 void ctkDoubleRangeSlider::onPositionsChanged(int min, int max)
 {
   CTK_D(const ctkDoubleRangeSlider);
   emit this->positionsChanged(d->minFromInt(min), d->maxFromInt(max));
 }
+
+// --------------------------------------------------------------------------
+ctkRangeSlider* ctkDoubleRangeSlider::slider()const
+{
+  CTK_D(const ctkDoubleRangeSlider);
+  return d->Slider;
+}
+
+// --------------------------------------------------------------------------
+void ctkDoubleRangeSlider::setSlider(ctkRangeSlider* slider)
+{
+  CTK_D(ctkDoubleRangeSlider);
+  slider->setOrientation(d->Slider->orientation());
+  slider->setMinimum(d->Slider->minimum());
+  slider->setMaximum(d->Slider->maximum());
+  slider->setValues(d->Slider->minimumValue(), d->Slider->maximumValue());
+  slider->setSingleStep(d->Slider->singleStep());
+  slider->setTracking(d->Slider->hasTracking());
+  slider->setTickInterval(d->Slider->tickInterval());
+  delete d->Slider;
+  qobject_cast<QHBoxLayout*>(this->layout())->addWidget(slider);
+  d->Slider = slider;
+  d->connectSlider();
+}

+ 6 - 0
Libs/Widgets/ctkDoubleRangeSlider.h

@@ -29,6 +29,7 @@
 #include <ctkPimpl.h>
 #include "CTKWidgetsExport.h"
 
+class ctkRangeSlider;
 class ctkDoubleRangeSliderPrivate;
 class CTK_WIDGETS_EXPORT ctkDoubleRangeSlider : public QWidget
 {
@@ -211,6 +212,11 @@ protected slots:
   void onMinPosChanged(int value);
   void onMaxPosChanged(int value);
   void onPositionsChanged(int min, int max);
+
+protected:
+  ctkRangeSlider* slider()const;
+  void setSlider(ctkRangeSlider* slider);
+
 private:
   CTK_DECLARE_PRIVATE(ctkDoubleRangeSlider);
 };

+ 13 - 3
Libs/Widgets/ctkRangeSlider.cpp

@@ -190,7 +190,7 @@ void ctkRangeSliderPrivate::drawMinimumSlider( QStylePainter* painter ) const
 {
   CTK_P(const ctkRangeSlider);
   QStyleOptionSlider option;
-  p->initStyleOption( &option );
+  p->initMinimumSliderStyleOption( &option );
 
   option.subControls = QStyle::SC_SliderHandle;
   option.sliderValue = m_MinimumValue;
@@ -210,7 +210,7 @@ void ctkRangeSliderPrivate::drawMaximumSlider( QStylePainter* painter ) const
 {
   CTK_P(const ctkRangeSlider);
   QStyleOptionSlider option;
-  p->Superclass::initStyleOption( &option );
+  p->initMaximumSliderStyleOption( &option );
 
   option.subControls = QStyle::SC_SliderHandle;
   option.sliderValue = m_MaximumValue;
@@ -220,7 +220,6 @@ void ctkRangeSliderPrivate::drawMaximumSlider( QStylePainter* painter ) const
     option.activeSubControls = QStyle::SC_SliderHandle;
     option.state |= QStyle::State_Sunken;
     }
-
   painter->drawComplexControl(QStyle::CC_Slider, option);
 }
 
@@ -661,3 +660,14 @@ void ctkRangeSlider::mouseReleaseEvent(QMouseEvent* mouseEvent)
   this->update();
 }
 
+// --------------------------------------------------------------------------
+void ctkRangeSlider::initMinimumSliderStyleOption(QStyleOptionSlider* option) const
+{
+  this->initStyleOption(option);
+}
+
+// --------------------------------------------------------------------------
+void ctkRangeSlider::initMaximumSliderStyleOption(QStyleOptionSlider* option) const
+{
+  this->initStyleOption(option);
+}

+ 2 - 0
Libs/Widgets/ctkRangeSlider.h

@@ -151,6 +151,8 @@ protected:
   // Description:
   // Rendering is done here.
   virtual void paintEvent(QPaintEvent* ev);
+  virtual void initMinimumSliderStyleOption(QStyleOptionSlider* option) const;
+  virtual void initMaximumSliderStyleOption(QStyleOptionSlider* option) const;
 
 private:
   CTK_DECLARE_PRIVATE(ctkRangeSlider);

+ 58 - 12
Libs/Widgets/ctkRangeWidget.cpp

@@ -32,6 +32,8 @@ class ctkRangeWidgetPrivate: public ctkPrivate<ctkRangeWidget>,
 {
 public:
   ctkRangeWidgetPrivate();
+  void connectSlider();
+
   void updateSpinBoxWidth();
   int synchronizedSpinBoxWidth()const;
   void synchronizeSiblingSpinBox(int newWidth);
@@ -64,6 +66,32 @@ ctkRangeWidgetPrivate::ctkRangeWidgetPrivate()
 }
 
 // --------------------------------------------------------------------------
+void ctkRangeWidgetPrivate::connectSlider()
+{
+  CTK_P(ctkRangeWidget);
+  QObject::connect(this->Slider, SIGNAL(valuesChanged(double, double)),
+                   p, SLOT(changeValues(double,double)));
+  QObject::connect(this->Slider, SIGNAL(minimumValueChanged(double)),
+                   p, SLOT(changeMinimumValue(double)));
+  QObject::connect(this->Slider, SIGNAL(maximumValueChanged(double)),
+                   p, SLOT(changeMaximumValue(double)));
+
+  QObject::connect(this->MinimumSpinBox, SIGNAL(valueChanged(double)),
+                   this->Slider, SLOT(setMinimumValue(double)));
+  QObject::connect(this->MaximumSpinBox, SIGNAL(valueChanged(double)),
+                   this->Slider, SLOT(setMaximumValue(double)));
+  QObject::connect(this->MinimumSpinBox, SIGNAL(valueChanged(double)),
+                   p, SLOT(setMinimumToMaximumSpinBox(double)));
+  QObject::connect(this->MaximumSpinBox, SIGNAL(valueChanged(double)),
+                   p, SLOT(setMaximumToMinimumSpinBox(double)));
+
+  QObject::connect(this->Slider, SIGNAL(sliderPressed()),
+                   p, SLOT(startChanging()));
+  QObject::connect(this->Slider, SIGNAL(sliderReleased()),
+                   p, SLOT(stopChanging()));
+}
+
+// --------------------------------------------------------------------------
 void ctkRangeWidgetPrivate::updateSpinBoxWidth()
 {
   int spinBoxWidth = this->synchronizedSpinBoxWidth();
@@ -158,19 +186,8 @@ ctkRangeWidget::ctkRangeWidget(QWidget* _parent) : Superclass(_parent)
   d->MinimumSpinBox->setValue(d->Slider->minimumValue());
   d->MaximumSpinBox->setValue(d->Slider->maximumValue());
   
-  //this->connect(d->Slider, SIGNAL(minimumValueChanged(double)), d->MinimumSpinBox, SLOT(setValue(double)));
-  //this->connect(d->Slider, SIGNAL(maximumValueChanged(double)), d->MaximumSpinBox, SLOT(setValue(double)));
-  this->connect(d->Slider, SIGNAL(valuesChanged(double, double)), this, SLOT(changeValues(double,double)));
-  this->connect(d->Slider, SIGNAL(minimumValueChanged(double)), this, SLOT(changeMinimumValue(double)));
-  this->connect(d->Slider, SIGNAL(maximumValueChanged(double)), this, SLOT(changeMaximumValue(double)));
-  
-  this->connect(d->MinimumSpinBox, SIGNAL(valueChanged(double)), d->Slider, SLOT(setMinimumValue(double)));
-  this->connect(d->MaximumSpinBox, SIGNAL(valueChanged(double)), d->Slider, SLOT(setMaximumValue(double)));
-  this->connect(d->MinimumSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setMinimumToMaximumSpinBox(double)));
-  this->connect(d->MaximumSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setMaximumToMinimumSpinBox(double)));
+  d->connectSlider();
 
-  this->connect(d->Slider, SIGNAL(sliderPressed()), this, SLOT(startChanging()));
-  this->connect(d->Slider, SIGNAL(sliderReleased()), this, SLOT(stopChanging()));
   d->MinimumSpinBox->installEventFilter(this);
   d->MaximumSpinBox->installEventFilter(this);
 }
@@ -599,3 +616,32 @@ void ctkRangeWidget::setAutoSpinBoxWidth(bool autoWidth)
   d->AutoSpinBoxWidth = autoWidth;
   d->updateSpinBoxWidth();
 }
+
+// -------------------------------------------------------------------------
+ctkDoubleRangeSlider* ctkRangeWidget::slider()const
+{
+  CTK_D(const ctkRangeWidget);
+  return d->Slider;
+}
+
+// -------------------------------------------------------------------------
+void ctkRangeWidget::setSlider(ctkDoubleRangeSlider* slider)
+{
+  CTK_D(ctkRangeWidget);
+
+  slider->setOrientation(d->Slider->orientation());
+  slider->setMinimum(d->Slider->minimum());
+  slider->setMaximum(d->Slider->maximum());
+  slider->setValues(d->Slider->minimumValue(), d->Slider->maximumValue());
+  slider->setSingleStep(d->Slider->singleStep());
+  slider->setTracking(d->Slider->hasTracking());
+  slider->setTickInterval(d->Slider->tickInterval());
+
+  delete d->Slider;
+  d->Slider = slider;
+
+  d->connectSlider();
+
+  d->relayout();
+}
+

+ 6 - 0
Libs/Widgets/ctkRangeWidget.h

@@ -29,6 +29,7 @@
 
 #include "CTKWidgetsExport.h"
 
+class ctkDoubleRangeSlider;
 class ctkRangeWidgetPrivate;
 
 ///
@@ -198,6 +199,11 @@ protected slots:
 
 protected:
   virtual bool eventFilter(QObject *obj, QEvent *event);
+
+  /// can be used to change the slider by a custom one
+  ctkDoubleRangeSlider* slider()const;
+  void setSlider(ctkDoubleRangeSlider* slider);
+
 private:
   CTK_DECLARE_PRIVATE(ctkRangeWidget);