From 8d3b90d815251e9a9675e2a3232f13db4e577bc4 Mon Sep 17 00:00:00 2001 From: David Vierra Date: Thu, 30 Mar 2017 03:55:13 -1000 Subject: [PATCH] SpinSlider no longer sets value back-and-forth between slider and spinbox Prevents feedback loops when float values can't be converted exactly --- src/mcedit2/widgets/spinslider.py | 46 ++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/src/mcedit2/widgets/spinslider.py b/src/mcedit2/widgets/spinslider.py index eff1584..0d09905 100644 --- a/src/mcedit2/widgets/spinslider.py +++ b/src/mcedit2/widgets/spinslider.py @@ -3,6 +3,8 @@ """ from __future__ import absolute_import, division, print_function import logging +from contextlib import contextmanager + from PySide import QtGui, QtCore from PySide.QtCore import Qt from mcedit2.util.load_ui import registerCustomWidget @@ -22,7 +24,9 @@ class SpinSlider(QtGui.QWidget): increment = kwargs.pop('increment', None) if increment is None: increment = 0.1 if isDouble else 1 - + + self._changing = False + self.isDouble = isDouble super(SpinSlider, self).__init__(*args, **kwargs) @@ -49,23 +53,49 @@ class SpinSlider(QtGui.QWidget): self.slider.sliderReleased.connect(self.sliderReleased) self.setLayout(Row(self.spinBox, self.slider, margin=0)) - + if minimum is not None: self.setMinimum(minimum) if maximum is not None: self.setMaximum(maximum) if value is not None: self.setValue(value) - + + @contextmanager + def suppressChanges(self): + try: + self._changing = True + yield + finally: + self._changing = False + + def toSlider(self, value): + return value * self.sliderFactor + + def fromSlider(self, value): + return value / self.sliderFactor + def spinBoxChanged(self, value): + if self._changing: + return + self._value = value - self.slider.setValue(value * self.sliderFactor) + + with self.suppressChanges(): + self.slider.setValue(self.toSlider(value)) + self.valueChanged.emit(value, False) def sliderChanged(self, value): - value /= self.sliderFactor + if self._changing: + return + + value = self.fromSlider(value) self._value = value - self.spinBox.setValue(value) + + with self.suppressChanges(): + self.spinBox.setValue(value) + self.valueChanged.emit(value, self.slider.isSliderDown()) def sliderReleased(self): @@ -77,7 +107,9 @@ class SpinSlider(QtGui.QWidget): def setValue(self, value): self._value = value self.spinBox.setValue(value) - self.slider.setValue(value * self.sliderFactor) + # if value is not None: + # value *= self.sliderFactor + # self.slider.setValue(value) def minimum(self): return self._minimum