Skip to content

Backport PR #21604 on branch v3.5.x (Fix centre square rectangle selector part 1) #21636

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
267 changes: 267 additions & 0 deletions lib/matplotlib/tests/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@ def test_rectangle_selector():
check_rectangle(props=dict(fill=True))


def _resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new,
use_key=None):
do_event(tool, 'press', xdata=xdata, ydata=ydata, button=1)
if use_key is not None:
do_event(tool, 'on_key_press', key=use_key)
do_event(tool, 'onmove', xdata=xdata_new, ydata=ydata_new, button=1)
if use_key is not None:
do_event(tool, 'on_key_release', key=use_key)
do_event(tool, 'release', xdata=xdata_new, ydata=ydata_new, button=1)

return tool


@pytest.mark.parametrize('drag_from_anywhere, new_center',
[[True, (60, 75)],
[False, (30, 20)]])
Expand Down Expand Up @@ -118,6 +131,260 @@ def onselect(epress, erelease):
assert artist.get_alpha() == 0.3


def test_rectangle_resize():
ax = get_ax()

def onselect(epress, erelease):
pass

tool = widgets.RectangleSelector(ax, onselect, interactive=True)
# Create rectangle
_resize_rectangle(tool, 0, 10, 100, 120)
assert tool.extents == (0.0, 100.0, 10.0, 120.0)

# resize NE handle
extents = tool.extents
xdata, ydata = extents[1], extents[3]
xdata_new, ydata_new = xdata + 10, ydata + 5
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
assert tool.extents == (extents[0], xdata_new, extents[2], ydata_new)

# resize E handle
extents = tool.extents
xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2
xdata_new, ydata_new = xdata + 10, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
assert tool.extents == (extents[0], xdata_new, extents[2], extents[3])

# resize W handle
extents = tool.extents
xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2
xdata_new, ydata_new = xdata + 15, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
assert tool.extents == (xdata_new, extents[1], extents[2], extents[3])

# resize SW handle
extents = tool.extents
xdata, ydata = extents[0], extents[2]
xdata_new, ydata_new = xdata + 20, ydata + 25
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
assert tool.extents == (xdata_new, extents[1], ydata_new, extents[3])


@pytest.mark.parametrize('use_default_state', [True, False])
def test_rectangle_resize_center(use_default_state):
ax = get_ax()

def onselect(epress, erelease):
pass

tool = widgets.RectangleSelector(ax, onselect, interactive=True)
# Create rectangle
_resize_rectangle(tool, 70, 65, 125, 130)
assert tool.extents == (70.0, 125.0, 65.0, 130.0)

if use_default_state:
tool._default_state.add('center')
use_key = None
else:
use_key = 'control'

# resize NE handle
extents = tool.extents
xdata, ydata = extents[1], extents[3]
xdiff, ydiff = 10, 5
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (extents[0] - xdiff, xdata_new,
extents[2] - ydiff, ydata_new)

# resize E handle
extents = tool.extents
xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2
xdiff = 10
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (extents[0] - xdiff, xdata_new,
extents[2], extents[3])

# resize E handle negative diff
extents = tool.extents
xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2
xdiff = -20
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (extents[0] - xdiff, xdata_new,
extents[2], extents[3])

# resize W handle
extents = tool.extents
xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2
xdiff = 15
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (xdata_new, extents[1] - xdiff,
extents[2], extents[3])

# resize W handle negative diff
extents = tool.extents
xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2
xdiff = -25
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (xdata_new, extents[1] - xdiff,
extents[2], extents[3])

# resize SW handle
extents = tool.extents
xdata, ydata = extents[0], extents[2]
xdiff, ydiff = 20, 25
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (xdata_new, extents[1] - xdiff,
ydata_new, extents[3] - ydiff)


@pytest.mark.parametrize('use_default_state', [True, False])
def test_rectangle_resize_square(use_default_state):
ax = get_ax()

def onselect(epress, erelease):
pass

tool = widgets.RectangleSelector(ax, onselect, interactive=True)
# Create rectangle
_resize_rectangle(tool, 70, 65, 120, 115)
assert tool.extents == (70.0, 120.0, 65.0, 115.0)

if use_default_state:
tool._default_state.add('square')
use_key = None
else:
use_key = 'shift'

# resize NE handle
extents = tool.extents
xdata, ydata = extents[1], extents[3]
xdiff, ydiff = 10, 5
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (extents[0], xdata_new,
extents[2], extents[3] + xdiff)

# resize E handle
extents = tool.extents
xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2
xdiff = 10
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (extents[0], xdata_new,
extents[2], extents[3] + xdiff)

# resize E handle negative diff
extents = tool.extents
xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2
xdiff = -20
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (extents[0], xdata_new,
extents[2], extents[3] + xdiff)

# resize W handle
extents = tool.extents
xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2
xdiff = 15
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (xdata_new, extents[1],
extents[2], extents[3] - xdiff)

# resize W handle negative diff
extents = tool.extents
xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2
xdiff = -25
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (xdata_new, extents[1],
extents[2], extents[3] - xdiff)

# resize SW handle
extents = tool.extents
xdata, ydata = extents[0], extents[2]
xdiff, ydiff = 20, 25
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new, use_key)
assert tool.extents == (extents[0] + ydiff, extents[1],
ydata_new, extents[3])


def test_rectangle_resize_square_center():
ax = get_ax()

def onselect(epress, erelease):
pass

tool = widgets.RectangleSelector(ax, onselect, interactive=True)
# Create rectangle
_resize_rectangle(tool, 70, 65, 120, 115)
tool._default_state.add('square')
tool._default_state.add('center')
assert tool.extents == (70.0, 120.0, 65.0, 115.0)

# resize NE handle
extents = tool.extents
xdata, ydata = extents[1], extents[3]
xdiff, ydiff = 10, 5
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
assert tool.extents == (extents[0] - xdiff, xdata_new,
extents[2] - xdiff, extents[3] + xdiff)

# resize E handle
extents = tool.extents
xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2
xdiff = 10
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
assert tool.extents == (extents[0] - xdiff, xdata_new,
extents[2] - xdiff, extents[3] + xdiff)

# resize E handle negative diff
extents = tool.extents
xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2
xdiff = -20
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
assert tool.extents == (extents[0] - xdiff, xdata_new,
extents[2] - xdiff, extents[3] + xdiff)

# resize W handle
extents = tool.extents
xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2
xdiff = 5
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
assert tool.extents == (xdata_new, extents[1] - xdiff,
extents[2] + xdiff, extents[3] - xdiff)

# resize W handle negative diff
extents = tool.extents
xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2
xdiff = -25
xdata_new, ydata_new = xdata + xdiff, ydata
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
assert tool.extents == (xdata_new, extents[1] - xdiff,
extents[2] + xdiff, extents[3] - xdiff)

# resize SW handle
extents = tool.extents
xdata, ydata = extents[0], extents[2]
xdiff, ydiff = 20, 25
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
assert tool.extents == (extents[0] + ydiff, extents[1] - ydiff,
ydata_new, extents[3] - ydiff)


def test_ellipse():
"""For ellipse, test out the key modifiers"""
ax = get_ax()
Expand Down
Loading