ctkDoubleSlider.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0.txt
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // QT includes
  15. #include <QDebug>
  16. #include <QHBoxLayout>
  17. #include <QHelpEvent>
  18. #include <QPointer>
  19. #include <QStyle>
  20. #include <QStyleOptionSlider>
  21. #include <QToolTip>
  22. // CTK includes
  23. #include "ctkDoubleSlider.h"
  24. #include "ctkValueProxy.h"
  25. // STD includes
  26. #include <limits>
  27. //-----------------------------------------------------------------------------
  28. // ctkSlider
  29. //-----------------------------------------------------------------------------
  30. class ctkSlider: public QSlider
  31. {
  32. public:
  33. ctkSlider(QWidget* parent);
  34. using QSlider::initStyleOption;
  35. };
  36. //-----------------------------------------------------------------------------
  37. ctkSlider::ctkSlider(QWidget* parent): QSlider(parent)
  38. {
  39. }
  40. //-----------------------------------------------------------------------------
  41. // ctkDoubleSliderPrivate
  42. //-----------------------------------------------------------------------------
  43. class ctkDoubleSliderPrivate
  44. {
  45. Q_DECLARE_PUBLIC(ctkDoubleSlider);
  46. protected:
  47. ctkDoubleSlider* const q_ptr;
  48. public:
  49. ctkDoubleSliderPrivate(ctkDoubleSlider& object);
  50. int toInt(double value)const;
  51. double fromInt(int value)const;
  52. double safeFromInt(int value)const;
  53. void init();
  54. void updateOffset(double value);
  55. ctkSlider* Slider;
  56. QString HandleToolTip;
  57. double Minimum;
  58. double Maximum;
  59. bool SettingRange;
  60. // we should have a Offset and SliderPositionOffset (and MinimumOffset?)
  61. double Offset;
  62. double SingleStep;
  63. double PageStep;
  64. double Value;
  65. /// Converts input value with displayed value
  66. QPointer<ctkValueProxy> Proxy;
  67. };
  68. // --------------------------------------------------------------------------
  69. ctkDoubleSliderPrivate::ctkDoubleSliderPrivate(ctkDoubleSlider& object)
  70. :q_ptr(&object)
  71. {
  72. this->Slider = 0;
  73. this->Minimum = 0.;
  74. this->Maximum = 100.;
  75. this->SettingRange = false;
  76. this->Offset = 0.;
  77. this->SingleStep = 1.;
  78. this->PageStep = 10.;
  79. this->Value = 0.;
  80. }
  81. // --------------------------------------------------------------------------
  82. void ctkDoubleSliderPrivate::init()
  83. {
  84. Q_Q(ctkDoubleSlider);
  85. this->Slider = new ctkSlider(q);
  86. this->Slider->installEventFilter(q);
  87. QHBoxLayout* l = new QHBoxLayout(q);
  88. l->addWidget(this->Slider);
  89. l->setContentsMargins(0,0,0,0);
  90. this->Minimum = this->Slider->minimum();
  91. this->Maximum = this->Slider->maximum();
  92. // this->Slider->singleStep is always 1
  93. this->SingleStep = this->Slider->singleStep();
  94. this->PageStep = this->Slider->pageStep();
  95. this->Value = this->Slider->value();
  96. q->connect(this->Slider, SIGNAL(valueChanged(int)), q, SLOT(onValueChanged(int)));
  97. q->connect(this->Slider, SIGNAL(sliderMoved(int)), q, SLOT(onSliderMoved(int)));
  98. q->connect(this->Slider, SIGNAL(sliderPressed()), q, SIGNAL(sliderPressed()));
  99. q->connect(this->Slider, SIGNAL(sliderReleased()), q, SIGNAL(sliderReleased()));
  100. q->connect(this->Slider, SIGNAL(rangeChanged(int,int)),
  101. q, SLOT(onRangeChanged(int,int)));
  102. q->setSizePolicy(this->Slider->sizePolicy());
  103. q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
  104. }
  105. // --------------------------------------------------------------------------
  106. int ctkDoubleSliderPrivate::toInt(double doubleValue)const
  107. {
  108. double tmp = doubleValue / this->SingleStep;
  109. static const double minInt = std::numeric_limits<int>::min();
  110. static const double maxInt = std::numeric_limits<int>::max();
  111. #ifndef QT_NO_DEBUG
  112. static const double maxDouble = std::numeric_limits<double>::max();
  113. if ( (tmp < minInt || tmp > maxInt) &&
  114. // If the value is the min or max double, there is no need
  115. // to warn. It is expected that the number is outside of bounds.
  116. (doubleValue != -maxDouble && doubleValue != maxDouble) )
  117. {
  118. qWarning() << __FUNCTION__ << ": value " << doubleValue
  119. << " for singleStep " << this->SingleStep
  120. << " is out of integer bounds !";
  121. }
  122. #endif
  123. tmp = qBound(minInt, tmp, maxInt);
  124. int intValue = qRound(tmp);
  125. //qDebug() << __FUNCTION__ << doubleValue << tmp << intValue;
  126. return intValue;
  127. }
  128. // --------------------------------------------------------------------------
  129. double ctkDoubleSliderPrivate::fromInt(int intValue)const
  130. {
  131. double doubleValue = this->SingleStep * (this->Offset + intValue) ;
  132. //qDebug() << __FUNCTION__ << intValue << doubleValue;
  133. return doubleValue;
  134. }
  135. // --------------------------------------------------------------------------
  136. double ctkDoubleSliderPrivate::safeFromInt(int intValue)const
  137. {
  138. return qBound(this->Minimum, this->fromInt(intValue), this->Maximum);
  139. }
  140. // --------------------------------------------------------------------------
  141. void ctkDoubleSliderPrivate::updateOffset(double value)
  142. {
  143. this->Offset = (value / this->SingleStep) - this->toInt(value);
  144. }
  145. //-----------------------------------------------------------------------------
  146. // ctkDoubleSlider
  147. // --------------------------------------------------------------------------
  148. ctkDoubleSlider::ctkDoubleSlider(QWidget* _parent) : Superclass(_parent)
  149. , d_ptr(new ctkDoubleSliderPrivate(*this))
  150. {
  151. Q_D(ctkDoubleSlider);
  152. d->init();
  153. }
  154. // --------------------------------------------------------------------------
  155. ctkDoubleSlider::ctkDoubleSlider(Qt::Orientation _orientation, QWidget* _parent)
  156. : Superclass(_parent)
  157. , d_ptr(new ctkDoubleSliderPrivate(*this))
  158. {
  159. Q_D(ctkDoubleSlider);
  160. d->init();
  161. this->setOrientation(_orientation);
  162. }
  163. // --------------------------------------------------------------------------
  164. ctkDoubleSlider::~ctkDoubleSlider()
  165. {
  166. }
  167. // --------------------------------------------------------------------------
  168. void ctkDoubleSlider::setMinimum(double min)
  169. {
  170. this->setRange(min, qMax(min, this->maximum()));
  171. }
  172. // --------------------------------------------------------------------------
  173. void ctkDoubleSlider::setMaximum(double max)
  174. {
  175. this->setRange(qMin(this->minimum(), max), max);
  176. }
  177. // --------------------------------------------------------------------------
  178. void ctkDoubleSlider::setRange(double newMin, double newMax)
  179. {
  180. Q_D(ctkDoubleSlider);
  181. if (d->Proxy)
  182. {
  183. newMin = d->Proxy.data()->proxyValueFromValue(newMin);
  184. newMax = d->Proxy.data()->proxyValueFromValue(newMax);
  185. }
  186. if (newMin > newMax)
  187. {
  188. qSwap(newMin, newMax);
  189. }
  190. double oldMin = d->Minimum;
  191. double oldMax = d->Maximum;
  192. d->Minimum = newMin;
  193. d->Maximum = newMax;
  194. if (d->Minimum >= d->Value)
  195. {
  196. d->updateOffset(d->Minimum);
  197. }
  198. if (d->Maximum <= d->Value)
  199. {
  200. d->updateOffset(d->Maximum);
  201. }
  202. bool wasSettingRange = d->SettingRange;
  203. d->SettingRange = true;
  204. d->Slider->setRange(d->toInt(newMin), d->toInt(newMax));
  205. d->SettingRange = wasSettingRange;
  206. if (!wasSettingRange && (d->Minimum != oldMin || d->Maximum != oldMax))
  207. {
  208. emit this->rangeChanged(this->minimum(), this->maximum());
  209. }
  210. /// In case QSlider::setRange(...) didn't notify the value
  211. /// has changed.
  212. this->setValue(this->value());
  213. }
  214. // --------------------------------------------------------------------------
  215. double ctkDoubleSlider::minimum()const
  216. {
  217. Q_D(const ctkDoubleSlider);
  218. double min = d->Minimum;
  219. double max = d->Maximum;
  220. if (d->Proxy)
  221. {
  222. min = d->Proxy.data()->valueFromProxyValue(min);
  223. max = d->Proxy.data()->valueFromProxyValue(max);
  224. }
  225. return qMin(min, max);
  226. }
  227. // --------------------------------------------------------------------------
  228. double ctkDoubleSlider::maximum()const
  229. {
  230. Q_D(const ctkDoubleSlider);
  231. double min = d->Minimum;
  232. double max = d->Maximum;
  233. if (d->Proxy)
  234. {
  235. min = d->Proxy.data()->valueFromProxyValue(min);
  236. max = d->Proxy.data()->valueFromProxyValue(max);
  237. }
  238. return qMax(min, max);
  239. }
  240. // --------------------------------------------------------------------------
  241. double ctkDoubleSlider::sliderPosition()const
  242. {
  243. Q_D(const ctkDoubleSlider);
  244. int intPosition = d->Slider->sliderPosition();
  245. double position = d->safeFromInt(intPosition);
  246. if (d->Proxy)
  247. {
  248. position = d->Proxy.data()->valueFromProxyValue(position);
  249. }
  250. return position;
  251. }
  252. // --------------------------------------------------------------------------
  253. void ctkDoubleSlider::setSliderPosition(double newPosition)
  254. {
  255. Q_D(ctkDoubleSlider);
  256. if (d->Proxy)
  257. {
  258. newPosition = d->Proxy.data()->proxyValueFromValue(newPosition);
  259. }
  260. int newIntPosition = d->toInt(newPosition);
  261. d->Slider->setSliderPosition(newIntPosition);
  262. }
  263. // --------------------------------------------------------------------------
  264. double ctkDoubleSlider::value()const
  265. {
  266. Q_D(const ctkDoubleSlider);
  267. double val = d->Value;
  268. if (d->Proxy)
  269. {
  270. val = d->Proxy.data()->valueFromProxyValue(val);
  271. }
  272. return val;
  273. }
  274. // --------------------------------------------------------------------------
  275. void ctkDoubleSlider::setValue(double newValue)
  276. {
  277. Q_D(ctkDoubleSlider);
  278. if (d->Proxy)
  279. {
  280. newValue = d->Proxy.data()->proxyValueFromValue(newValue);
  281. }
  282. newValue = qBound(d->Minimum, newValue, d->Maximum);
  283. d->updateOffset(newValue);
  284. int newIntValue = d->toInt(newValue);
  285. if (newIntValue != d->Slider->value())
  286. {
  287. // d->Slider will emit a valueChanged signal that is connected to
  288. // ctkDoubleSlider::onValueChanged
  289. d->Slider->setValue(newIntValue);
  290. }
  291. else
  292. {
  293. double oldValue = d->Value;
  294. d->Value = newValue;
  295. // don't emit a valuechanged signal if the new value is quite
  296. // similar to the old value.
  297. if (qAbs(newValue - oldValue) > (d->SingleStep * 0.000000001))
  298. {
  299. emit this->valueChanged(this->value());
  300. }
  301. }
  302. }
  303. // --------------------------------------------------------------------------
  304. double ctkDoubleSlider::singleStep()const
  305. {
  306. Q_D(const ctkDoubleSlider);
  307. double step = d->SingleStep;
  308. return step;
  309. }
  310. // --------------------------------------------------------------------------
  311. void ctkDoubleSlider::setSingleStep(double newStep)
  312. {
  313. Q_D(ctkDoubleSlider);
  314. if (!this->isValidStep(newStep))
  315. {
  316. qWarning() << "ctkDoubleSlider::setSingleStep("<< newStep <<")"
  317. << "is outside of valid bounds.";
  318. return;
  319. }
  320. d->SingleStep = newStep;
  321. d->updateOffset(d->Value);
  322. // update the new values of the QSlider
  323. bool oldBlockSignals = d->Slider->blockSignals(true);
  324. d->Slider->setRange(d->toInt(d->Minimum), d->toInt(d->Maximum));
  325. d->Slider->setValue(d->toInt(d->Value));
  326. d->Slider->setPageStep(d->toInt(d->PageStep));
  327. d->Slider->blockSignals(oldBlockSignals);
  328. Q_ASSERT(qFuzzyCompare(d->Value,d->safeFromInt(d->Slider->value())));
  329. }
  330. // --------------------------------------------------------------------------
  331. bool ctkDoubleSlider::isValidStep(double step)const
  332. {
  333. Q_D(const ctkDoubleSlider);
  334. if (d->Minimum == d->Maximum)
  335. {
  336. return true;
  337. }
  338. const double minStep = qMax(d->Maximum / std::numeric_limits<double>::max(),
  339. std::numeric_limits<double>::epsilon());
  340. const double maxStep = qMin(d->Maximum - d->Minimum,
  341. static_cast<double>(std::numeric_limits<int>::max()));
  342. return step >= minStep && step <= maxStep;
  343. }
  344. // --------------------------------------------------------------------------
  345. double ctkDoubleSlider::pageStep()const
  346. {
  347. Q_D(const ctkDoubleSlider);
  348. return d->PageStep;
  349. }
  350. // --------------------------------------------------------------------------
  351. void ctkDoubleSlider::setPageStep(double newStep)
  352. {
  353. Q_D(ctkDoubleSlider);
  354. d->PageStep = newStep;
  355. int intPageStep = d->toInt(d->PageStep);
  356. d->Slider->setPageStep(intPageStep);
  357. }
  358. // --------------------------------------------------------------------------
  359. double ctkDoubleSlider::tickInterval()const
  360. {
  361. Q_D(const ctkDoubleSlider);
  362. // No need to apply Offset
  363. double interval = d->SingleStep * d->Slider->tickInterval();
  364. return interval;
  365. }
  366. // --------------------------------------------------------------------------
  367. void ctkDoubleSlider::setTickInterval(double newInterval)
  368. {
  369. Q_D(ctkDoubleSlider);
  370. int newIntInterval = d->toInt(newInterval);
  371. d->Slider->setTickInterval(newIntInterval);
  372. }
  373. // --------------------------------------------------------------------------
  374. QSlider::TickPosition ctkDoubleSlider::tickPosition()const
  375. {
  376. Q_D(const ctkDoubleSlider);
  377. return d->Slider->tickPosition();
  378. }
  379. // --------------------------------------------------------------------------
  380. void ctkDoubleSlider::setTickPosition(QSlider::TickPosition newTickPosition)
  381. {
  382. Q_D(ctkDoubleSlider);
  383. d->Slider->setTickPosition(newTickPosition);
  384. }
  385. // --------------------------------------------------------------------------
  386. bool ctkDoubleSlider::hasTracking()const
  387. {
  388. Q_D(const ctkDoubleSlider);
  389. return d->Slider->hasTracking();
  390. }
  391. // --------------------------------------------------------------------------
  392. void ctkDoubleSlider::setTracking(bool enable)
  393. {
  394. Q_D(ctkDoubleSlider);
  395. d->Slider->setTracking(enable);
  396. }
  397. // --------------------------------------------------------------------------
  398. bool ctkDoubleSlider::invertedAppearance()const
  399. {
  400. Q_D(const ctkDoubleSlider);
  401. return d->Slider->invertedAppearance();
  402. }
  403. // --------------------------------------------------------------------------
  404. void ctkDoubleSlider::setInvertedAppearance(bool invertedAppearance)
  405. {
  406. Q_D(ctkDoubleSlider);
  407. d->Slider->setInvertedAppearance(invertedAppearance);
  408. }
  409. // --------------------------------------------------------------------------
  410. bool ctkDoubleSlider::invertedControls()const
  411. {
  412. Q_D(const ctkDoubleSlider);
  413. return d->Slider->invertedControls();
  414. }
  415. // --------------------------------------------------------------------------
  416. void ctkDoubleSlider::setInvertedControls(bool invertedControls)
  417. {
  418. Q_D(ctkDoubleSlider);
  419. d->Slider->setInvertedControls(invertedControls);
  420. }
  421. // --------------------------------------------------------------------------
  422. void ctkDoubleSlider::triggerAction( QAbstractSlider::SliderAction action)
  423. {
  424. Q_D(ctkDoubleSlider);
  425. d->Slider->triggerAction(action);
  426. }
  427. // --------------------------------------------------------------------------
  428. Qt::Orientation ctkDoubleSlider::orientation()const
  429. {
  430. Q_D(const ctkDoubleSlider);
  431. return d->Slider->orientation();
  432. }
  433. // --------------------------------------------------------------------------
  434. void ctkDoubleSlider::setOrientation(Qt::Orientation newOrientation)
  435. {
  436. Q_D(ctkDoubleSlider);
  437. if (this->orientation() == newOrientation)
  438. {
  439. return;
  440. }
  441. if (!testAttribute(Qt::WA_WState_OwnSizePolicy))
  442. {
  443. QSizePolicy sp = this->sizePolicy();
  444. sp.transpose();
  445. this->setSizePolicy(sp);
  446. this->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
  447. }
  448. // d->Slider will take care of calling updateGeometry
  449. d->Slider->setOrientation(newOrientation);
  450. }
  451. // --------------------------------------------------------------------------
  452. QString ctkDoubleSlider::handleToolTip()const
  453. {
  454. Q_D(const ctkDoubleSlider);
  455. return d->HandleToolTip;
  456. }
  457. // --------------------------------------------------------------------------
  458. void ctkDoubleSlider::setHandleToolTip(const QString& toolTip)
  459. {
  460. Q_D(ctkDoubleSlider);
  461. d->HandleToolTip = toolTip;
  462. }
  463. // --------------------------------------------------------------------------
  464. void ctkDoubleSlider::onValueChanged(int newValue)
  465. {
  466. Q_D(ctkDoubleSlider);
  467. double doubleNewValue = d->safeFromInt(newValue);
  468. /*
  469. qDebug() << "onValueChanged: " << newValue << "->"<< d->fromInt(newValue+d->Offset)
  470. << " old: " << d->Value << "->" << d->toInt(d->Value)
  471. << "offset:" << d->Offset << doubleNewValue;
  472. */
  473. if (d->Value == doubleNewValue)
  474. {
  475. return;
  476. }
  477. d->Value = doubleNewValue;
  478. emit this->valueChanged(this->value());
  479. }
  480. // --------------------------------------------------------------------------
  481. void ctkDoubleSlider::onSliderMoved(int newPosition)
  482. {
  483. Q_D(const ctkDoubleSlider);
  484. emit this->sliderMoved(d->safeFromInt(newPosition));
  485. }
  486. // --------------------------------------------------------------------------
  487. void ctkDoubleSlider::onRangeChanged(int newIntMin, int newIntMax)
  488. {
  489. Q_D(const ctkDoubleSlider);
  490. if (d->SettingRange)
  491. {
  492. return;
  493. }
  494. double newMin = d->fromInt(newIntMin);
  495. double newMax = d->fromInt(newIntMax);
  496. if (d->Proxy)
  497. {
  498. newMin = d->Proxy.data()->valueFromProxyValue(newMin);
  499. newMax = d->Proxy.data()->valueFromProxyValue(newMax);
  500. }
  501. this->setRange(newMin, newMax);
  502. }
  503. // --------------------------------------------------------------------------
  504. bool ctkDoubleSlider::eventFilter(QObject* watched, QEvent* event)
  505. {
  506. Q_D(ctkDoubleSlider);
  507. if (watched == d->Slider)
  508. {
  509. switch(event->type())
  510. {
  511. case QEvent::ToolTip:
  512. {
  513. QHelpEvent* helpEvent = static_cast<QHelpEvent*>(event);
  514. QStyleOptionSlider opt;
  515. d->Slider->initStyleOption(&opt);
  516. QStyle::SubControl hoveredControl =
  517. d->Slider->style()->hitTestComplexControl(
  518. QStyle::CC_Slider, &opt, helpEvent->pos(), this);
  519. if (!d->HandleToolTip.isEmpty() &&
  520. hoveredControl == QStyle::SC_SliderHandle)
  521. {
  522. QToolTip::showText(helpEvent->globalPos(), d->HandleToolTip.arg(this->value()));
  523. event->accept();
  524. return true;
  525. }
  526. }
  527. default:
  528. break;
  529. }
  530. }
  531. return this->Superclass::eventFilter(watched, event);
  532. }
  533. // --------------------------------------------------------------------------
  534. QSlider* ctkDoubleSlider::slider()const
  535. {
  536. Q_D(const ctkDoubleSlider);
  537. return d->Slider;
  538. }
  539. //----------------------------------------------------------------------------
  540. void ctkDoubleSlider::setValueProxy(ctkValueProxy* proxy)
  541. {
  542. Q_D(ctkDoubleSlider);
  543. if (proxy == d->Proxy.data())
  544. {
  545. return;
  546. }
  547. this->onValueProxyAboutToBeModified();
  548. if (d->Proxy.data())
  549. {
  550. disconnect(d->Proxy.data(), 0, this, 0);
  551. }
  552. d->Proxy = proxy;
  553. if (d->Proxy)
  554. {
  555. connect(d->Proxy.data(), SIGNAL(proxyAboutToBeModified()),
  556. this, SLOT(onValueProxyAboutToBeModified()));
  557. connect(d->Proxy.data(), SIGNAL(proxyModified()),
  558. this, SLOT(onValueProxyModified()));
  559. }
  560. this->onValueProxyModified();
  561. }
  562. //----------------------------------------------------------------------------
  563. ctkValueProxy* ctkDoubleSlider::valueProxy() const
  564. {
  565. Q_D(const ctkDoubleSlider);
  566. return d->Proxy.data();
  567. }
  568. // --------------------------------------------------------------------------
  569. void ctkDoubleSlider::onValueProxyAboutToBeModified()
  570. {
  571. Q_D(ctkDoubleSlider);
  572. d->Slider->setProperty("inputValue", this->value());
  573. d->Slider->setProperty("inputMinimum", this->minimum());
  574. d->Slider->setProperty("inputMaximum", this->maximum());
  575. }
  576. // --------------------------------------------------------------------------
  577. void ctkDoubleSlider::onValueProxyModified()
  578. {
  579. Q_D(ctkDoubleSlider);
  580. bool wasBlockingSignals = this->blockSignals(true);
  581. bool wasSettingRange = d->SettingRange;
  582. d->SettingRange = true;
  583. this->setRange(d->Slider->property("inputMinimum").toDouble(),
  584. d->Slider->property("inputMaximum").toDouble());
  585. d->SettingRange = wasSettingRange;
  586. this->setValue(d->Slider->property("inputValue").toDouble());
  587. this->blockSignals(wasBlockingSignals);
  588. }