InfiniteLine: Fix bounding box for differing x and y ranges
Previously, the same pixel -> local transform was used for both direction, which breaks if the displayed coordinate range is not the same for both axes.
This commit is contained in:
parent
ed009d3779
commit
ebc192dafd
@ -300,28 +300,28 @@ class InfiniteLine(GraphicsObject):
|
||||
vr = self.viewRect() # bounds of containing ViewBox mapped to local coords.
|
||||
if vr is None:
|
||||
return QtCore.QRectF()
|
||||
|
||||
## add a 4-pixel radius around the line for mouse interaction.
|
||||
|
||||
px = self.pixelLength(direction=Point(1,0), ortho=True) ## get pixel length orthogonal to the line
|
||||
if px is None:
|
||||
px = 0
|
||||
pw = max(self.pen.width() / 2, self.hoverPen.width() / 2)
|
||||
w = max(4, self._maxMarkerSize + pw) + 1
|
||||
w = w * px
|
||||
br = QtCore.QRectF(vr)
|
||||
br.setBottom(-w)
|
||||
br.setTop(w)
|
||||
|
||||
length = br.width()
|
||||
left = br.left() + length * self.span[0]
|
||||
right = br.left() + length * self.span[1]
|
||||
br.setLeft(left)
|
||||
br.setRight(right)
|
||||
# Compute width of area around line to use for mouse interaction, in
|
||||
# pixels (at least 4 for thin lines).
|
||||
penWidth = max(self.pen.width() / 2, self.hoverPen.width() / 2)
|
||||
padding = max(4, self._maxMarkerSize + penWidth) + 1
|
||||
|
||||
br = QtCore.QRectF()
|
||||
|
||||
orthoPadding = padding * (self.pixelLength(direction=Point(1,0), ortho=True) or 0)
|
||||
br.setBottom(-orthoPadding)
|
||||
br.setTop(orthoPadding)
|
||||
|
||||
paraPadding = padding * (self.pixelLength(direction=Point(1,0)) or 0)
|
||||
length = vr.width()
|
||||
left = vr.left() + length * self.span[0]
|
||||
right = vr.left() + length * self.span[1]
|
||||
br.setLeft(left - paraPadding)
|
||||
br.setRight(right + paraPadding)
|
||||
|
||||
br = br.normalized()
|
||||
|
||||
|
||||
vs = self.getViewBox().size()
|
||||
|
||||
if self._bounds != br or self._lastViewSize != vs:
|
||||
self._bounds = br
|
||||
self._lastViewSize = vs
|
||||
|
@ -44,7 +44,48 @@ def test_InfiniteLine():
|
||||
px = pg.Point(-0.5, -1.0 / 3**0.5)
|
||||
assert br.containsPoint(pos + 5 * px, QtCore.Qt.OddEvenFill)
|
||||
assert not br.containsPoint(pos + 7 * px, QtCore.Qt.OddEvenFill)
|
||||
|
||||
|
||||
|
||||
def test_InfiniteLine_scaled_bounding_box():
|
||||
# Make plot with unequal axis ranges.
|
||||
plt = pg.plot()
|
||||
plt.setXRange(0, 1)
|
||||
plt.setYRange(0, 1e-3)
|
||||
plt.resize(400, 400)
|
||||
|
||||
QtTest.QTest.qWaitForWindowShown(plt)
|
||||
QtTest.QTest.qWait(100)
|
||||
|
||||
# Vertical line.
|
||||
vline = pg.InfiniteLine(angle=90)
|
||||
vline.setPos(0.5)
|
||||
plt.addItem(vline)
|
||||
|
||||
# Make sure there is some padding around the line...
|
||||
vbr = vline.mapToScene(vline.boundingRect())
|
||||
def contains(rect, x, y):
|
||||
return rect.containsPoint(pg.Point(x, y), QtCore.Qt.OddEvenFill)
|
||||
assert contains(vbr, 221, -1)
|
||||
assert contains(vbr, 229, 381)
|
||||
|
||||
# ... but not too much.
|
||||
assert not contains(vbr, 221, -10)
|
||||
assert not contains(vbr, 210, -1)
|
||||
assert not contains(vbr, 229, 390)
|
||||
assert not contains(vbr, 240, 381)
|
||||
|
||||
# Same for horizontal line.
|
||||
hline = pg.InfiniteLine(angle=0)
|
||||
hline.setPos(0.5e-3)
|
||||
plt.addItem(hline)
|
||||
hbr = hline.mapToScene(hline.boundingRect())
|
||||
assert contains(hbr, 47, 185)
|
||||
assert contains(hbr, 403, 194)
|
||||
assert not contains(hbr, 47, 175)
|
||||
assert not contains(hbr, 37, 185)
|
||||
assert not contains(hbr, 413, 194)
|
||||
assert not contains(hbr, 403, 204)
|
||||
|
||||
|
||||
def test_mouseInteraction():
|
||||
plt = pg.plot()
|
||||
|
Loading…
Reference in New Issue
Block a user