mirror of
https://github.com/pyapp-kit/superqt.git
synced 2026-01-04 11:21:09 +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
|
return self.value() * p
|
||||||
|
|
||||||
def _post_get_hook(self, value: int) -> float:
|
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:
|
def _pre_set_hook(self, value: float) -> int:
|
||||||
return int(value * self._multiplier)
|
return int(value * self._multiplier)
|
||||||
|
|||||||
@@ -8,42 +8,35 @@ class _HookedSlider(QSlider):
|
|||||||
def _pre_set_hook(self, value):
|
def _pre_set_hook(self, value):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def value(self) -> float: # type: ignore[override]
|
def value(self):
|
||||||
return float(self._post_get_hook(super().value()))
|
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))
|
super().setValue(self._pre_set_hook(value))
|
||||||
|
|
||||||
def minimum(self) -> float: # type: ignore[override]
|
def minimum(self):
|
||||||
return self._post_get_hook(super().minimum())
|
return self._post_get_hook(super().minimum())
|
||||||
|
|
||||||
def setMinimum(self, minimum: float):
|
def setMinimum(self, minimum):
|
||||||
super().setMinimum(self._pre_set_hook(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())
|
return self._post_get_hook(super().maximum())
|
||||||
|
|
||||||
def setMaximum(self, maximum: float):
|
def setMaximum(self, maximum):
|
||||||
super().setMaximum(self._pre_set_hook(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())
|
return self._post_get_hook(super().singleStep())
|
||||||
|
|
||||||
def setSingleStep(self, step: float):
|
def setSingleStep(self, step):
|
||||||
super().setSingleStep(self._pre_set_hook(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())
|
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))
|
super().setPageStep(self._pre_set_hook(step))
|
||||||
|
|
||||||
def setRange(self, min: float, max: float) -> None:
|
def setRange(self, min: float, max: float) -> None:
|
||||||
super().setRange(self._pre_set_hook(min), self._pre_set_hook(max))
|
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
|
horizontal = self.orientation() == Qt.Horizontal
|
||||||
labels_above = self._handle_label_position == LabelPosition.LabelsAbove
|
labels_above = self._handle_label_position == LabelPosition.LabelsAbove
|
||||||
|
|
||||||
|
last_edge = None
|
||||||
for label, rect in zip(self._handle_labels, self._slider._handleRects()):
|
for label, rect in zip(self._handle_labels, self._slider._handleRects()):
|
||||||
dx = -label.width() / 2
|
dx = -label.width() / 2
|
||||||
dy = -label.height() / 2
|
dy = -label.height() / 2
|
||||||
@@ -250,7 +251,14 @@ class QLabeledRangeSlider(SliderProxy, QAbstractSlider):
|
|||||||
dx *= 3
|
dx *= 3
|
||||||
pos = self._slider.mapToParent(rect.center())
|
pos = self._slider.mapToParent(rect.center())
|
||||||
pos += QPoint(int(dx + self.label_shift_x), int(dy + self.label_shift_y))
|
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)
|
label.move(pos)
|
||||||
|
last_edge = pos
|
||||||
label.clearFocus()
|
label.clearFocus()
|
||||||
|
|
||||||
def _min_label_edited(self, val):
|
def _min_label_edited(self, val):
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ class QRangeSlider(_HookedSlider, QSlider):
|
|||||||
self._repeatMultiplier = 1 # TODO
|
self._repeatMultiplier = 1 # TODO
|
||||||
# for wheel nav
|
# for wheel nav
|
||||||
self._offset_accum = 0
|
self._offset_accum = 0
|
||||||
|
# fraction of total range to scroll when holding Ctrl while scrolling
|
||||||
|
self._control_fraction = 0.04
|
||||||
|
|
||||||
# color
|
# color
|
||||||
self._style = RangeSliderStyle()
|
self._style = RangeSliderStyle()
|
||||||
@@ -483,11 +485,12 @@ class QRangeSlider(_HookedSlider, QSlider):
|
|||||||
|
|
||||||
def _neighbor_bound(self, val: int, index: int, _lst: List[int]) -> int:
|
def _neighbor_bound(self, val: int, index: int, _lst: List[int]) -> int:
|
||||||
# make sure we don't go lower than any preceding index:
|
# make sure we don't go lower than any preceding index:
|
||||||
|
min_dist = self._post_get_hook(self.singleStep())
|
||||||
if index > 0:
|
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:
|
# make sure we don't go higher than any following index:
|
||||||
if index < len(_lst) - 1:
|
if index < (len(_lst) - 1):
|
||||||
val = min(_lst[index + 1], val)
|
val = min(_lst[index + 1] - min_dist, val)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def wheelEvent(self, e: QtGui.QWheelEvent) -> None:
|
def wheelEvent(self, e: QtGui.QWheelEvent) -> None:
|
||||||
@@ -509,10 +512,17 @@ class QRangeSlider(_HookedSlider, QSlider):
|
|||||||
if orientation == Qt.Horizontal:
|
if orientation == Qt.Horizontal:
|
||||||
delta *= -1
|
delta *= -1
|
||||||
offset = delta / 120
|
offset = delta / 120
|
||||||
if modifiers & Qt.ControlModifier or modifiers & Qt.ShiftModifier:
|
if modifiers & Qt.ShiftModifier:
|
||||||
# Scroll one page regardless of delta:
|
# Scroll one page regardless of delta:
|
||||||
steps_to_scroll = _bound(-pg_step, pg_step, int(offset * pg_step))
|
steps_to_scroll = _bound(-pg_step, pg_step, int(offset * pg_step))
|
||||||
self._offset_accum = 0
|
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:
|
else:
|
||||||
# Calculate how many lines to scroll. Depending on what delta is (and
|
# 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
|
# offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
|
||||||
|
|||||||
Reference in New Issue
Block a user