mirror of
https://github.com/pyapp-kit/superqt.git
synced 2025-12-16 03:00:05 +01:00
Prevent handle and label overlap (#7)
* cov changes * mostly good * remove cov * use int * fix * prevent label overlap
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user