diff --git a/qtrangeslider/_float_slider.py b/qtrangeslider/_float_slider.py index ec78869..59f5f03 100644 --- a/qtrangeslider/_float_slider.py +++ b/qtrangeslider/_float_slider.py @@ -63,7 +63,7 @@ class QDoubleSlider(_HookedSlider): return self.value() * p def _post_get_hook(self, value: int) -> float: - return value / self._multiplier + return float(value / self._multiplier) def _pre_set_hook(self, value: float) -> int: return int(value * self._multiplier) diff --git a/qtrangeslider/_hooked.py b/qtrangeslider/_hooked.py index 4fa8f3c..f1e4028 100644 --- a/qtrangeslider/_hooked.py +++ b/qtrangeslider/_hooked.py @@ -8,42 +8,35 @@ class _HookedSlider(QSlider): def _pre_set_hook(self, value): return value - def value(self) -> float: # type: ignore[override] - return float(self._post_get_hook(super().value())) + def value(self): + return self._post_get_hook(super().value()) - def setValue(self, value: float) -> None: + def setValue(self, value) -> None: super().setValue(self._pre_set_hook(value)) - def minimum(self) -> float: # type: ignore[override] + def minimum(self): return self._post_get_hook(super().minimum()) - def setMinimum(self, minimum: float): + def setMinimum(self, minimum): super().setMinimum(self._pre_set_hook(minimum)) - def maximum(self) -> float: # type: ignore[override] + def maximum(self): return self._post_get_hook(super().maximum()) - def setMaximum(self, maximum: float): + def setMaximum(self, maximum): super().setMaximum(self._pre_set_hook(maximum)) - def singleStep(self) -> float: # type: ignore[override] + def singleStep(self): return self._post_get_hook(super().singleStep()) - def setSingleStep(self, step: float): + def setSingleStep(self, step): super().setSingleStep(self._pre_set_hook(step)) - def pageStep(self) -> float: # type: ignore[override] + def pageStep(self): return self._post_get_hook(super().pageStep()) - def setPageStep(self, step: float) -> None: + def setPageStep(self, step) -> None: super().setPageStep(self._pre_set_hook(step)) def setRange(self, min: float, max: float) -> None: super().setRange(self._pre_set_hook(min), self._pre_set_hook(max)) - - # def sliderChange(self, change) -> None: - # if change == QSlider.SliderValueChange: - # self.valueChanged.emit(self.value()) - # if change == QSlider.SliderRangeChange: - # self.rangeChanged.emit(self.minimum(), self.maximum()) - # return super().sliderChange(change) diff --git a/qtrangeslider/_labeled.py b/qtrangeslider/_labeled.py index 8abe9f0..cebf553 100644 --- a/qtrangeslider/_labeled.py +++ b/qtrangeslider/_labeled.py @@ -235,6 +235,7 @@ class QLabeledRangeSlider(SliderProxy, QAbstractSlider): horizontal = self.orientation() == Qt.Horizontal labels_above = self._handle_label_position == LabelPosition.LabelsAbove + last_edge = None for label, rect in zip(self._handle_labels, self._slider._handleRects()): dx = -label.width() / 2 dy = -label.height() / 2 @@ -250,7 +251,14 @@ class QLabeledRangeSlider(SliderProxy, QAbstractSlider): dx *= 3 pos = self._slider.mapToParent(rect.center()) pos += QPoint(int(dx + self.label_shift_x), int(dy + self.label_shift_y)) + if last_edge is not None: + # prevent label overlap + if horizontal: + pos.setX(int(max(pos.x(), last_edge.x() + label.width() / 2 + 12))) + else: + pos.setY(int(min(pos.y(), last_edge.y() - label.height() / 2 - 4))) label.move(pos) + last_edge = pos label.clearFocus() def _min_label_edited(self, val): diff --git a/qtrangeslider/_qrangeslider.py b/qtrangeslider/_qrangeslider.py index 7ca4a31..47d2eeb 100644 --- a/qtrangeslider/_qrangeslider.py +++ b/qtrangeslider/_qrangeslider.py @@ -69,6 +69,8 @@ class QRangeSlider(_HookedSlider, QSlider): self._repeatMultiplier = 1 # TODO # for wheel nav self._offset_accum = 0 + # fraction of total range to scroll when holding Ctrl while scrolling + self._control_fraction = 0.04 # color self._style = RangeSliderStyle() @@ -483,11 +485,12 @@ class QRangeSlider(_HookedSlider, QSlider): def _neighbor_bound(self, val: int, index: int, _lst: List[int]) -> int: # make sure we don't go lower than any preceding index: + min_dist = self._post_get_hook(self.singleStep()) if index > 0: - val = max(_lst[index - 1], val) + val = max(_lst[index - 1] + min_dist, val) # make sure we don't go higher than any following index: - if index < len(_lst) - 1: - val = min(_lst[index + 1], val) + if index < (len(_lst) - 1): + val = min(_lst[index + 1] - min_dist, val) return val def wheelEvent(self, e: QtGui.QWheelEvent) -> None: @@ -509,10 +512,17 @@ class QRangeSlider(_HookedSlider, QSlider): if orientation == Qt.Horizontal: delta *= -1 offset = delta / 120 - if modifiers & Qt.ControlModifier or modifiers & Qt.ShiftModifier: + if modifiers & Qt.ShiftModifier: # Scroll one page regardless of delta: steps_to_scroll = _bound(-pg_step, pg_step, int(offset * pg_step)) self._offset_accum = 0 + elif modifiers & Qt.ControlModifier: + # Scroll one page regardless of delta: + _range = self._pre_set_hook(self.maximum()) - self._pre_set_hook( + self.minimum() + ) + steps_to_scroll = offset * _range * self._control_fraction + self._offset_accum = 0 else: # Calculate how many lines to scroll. Depending on what delta is (and # offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can