diff --git a/lib/matplotlib/tests/test_widgets.py b/lib/matplotlib/tests/test_widgets.py index 585d846944e8..5b960c32aa6e 100644 --- a/lib/matplotlib/tests/test_widgets.py +++ b/lib/matplotlib/tests/test_widgets.py @@ -1458,10 +1458,10 @@ def test_polygon_selector(draw_bounding_box): *polygon_place_vertex(50, 150), *polygon_place_vertex(50, 50), ('on_key_press', dict(key='shift')), + ('onmove', dict(xdata=75, ydata=75)), + ('press', dict(xdata=75, ydata=75)), ('onmove', dict(xdata=100, ydata=100)), - ('press', dict(xdata=100, ydata=100)), - ('onmove', dict(xdata=125, ydata=125)), - ('release', dict(xdata=125, ydata=125)), + ('release', dict(xdata=100, ydata=100)), ('on_key_release', dict(key='shift')), ] check_selector(event_sequence, expected_result, 2) @@ -1704,6 +1704,35 @@ def test_polygon_selector_clear_method(ax): np.testing.assert_equal(artist.get_xydata(), [(0, 0)]) +def test_polygon_selector_move(ax): + onselect = mock.Mock(spec=noop, return_value=None) + tool = widgets.PolygonSelector(ax, onselect) + vertices = [(10, 40), (50, 90), (30, 20)] + tool.verts = vertices + assert tool._selected + + # don't move polygon when pointer is outside of the polygon + press_data = (100, 100) + release_data = (110, 110) + click_and_drag(tool, start=press_data, end=release_data, key="shift") + assert tool.verts == vertices + assert not tool._selected + + # don't move polygon when shift key is not press + press_data = (25, 45) + release_data = (35, 55) + click_and_drag(tool, start=press_data, end=release_data, key=None) + assert tool.verts == vertices + assert tool._selected + + # move polygon when the pointer is on polygon + press_data = (25, 35) + release_data = (35, 45) + click_and_drag(tool, start=press_data, end=release_data, key="shift") + assert tool._selected + np.testing.assert_allclose(tool.verts, np.array(vertices) + 10) + + @pytest.mark.parametrize("horizOn", [False, True]) @pytest.mark.parametrize("vertOn", [False, True]) def test_MultiCursor(horizOn, vertOn): diff --git a/lib/matplotlib/widgets.py b/lib/matplotlib/widgets.py index 9c676574310c..96b1e66dc791 100644 --- a/lib/matplotlib/widgets.py +++ b/lib/matplotlib/widgets.py @@ -2125,6 +2125,9 @@ def __init__(self, ax, onselect=None, useblit=False, button=None, self._eventrelease = None self._prev_event = None self._state = set() + # keep track if selector is selected or not + # Default to True + self._selected = True def set_active(self, active): super().set_active(active) @@ -2352,8 +2355,9 @@ def get_visible(self): def clear(self): """Clear the selection and set the selector ready to make a new one.""" - self._clear_without_update() - self.update() + if self._selected: + self._clear_without_update() + self.update() def _clear_without_update(self): self._selection_completed = False @@ -3937,6 +3941,14 @@ def _press(self, event): h_idx, h_dist = self._polygon_handles.closest(event.x, event.y) if h_dist < self.grab_range: self._active_handle_idx = h_idx + # Only check if contains when polygon is completed + if self._selection_completed: + # contains shape + handle + contains = self._contains(event) or self._active_handle_idx >= 0 + if contains != self._selected: + self._selected = contains + self._polygon_handles.set_visible(self._selected) + self._draw_polygon() # Save the vertex positions at the time of the press event (needed to # support the 'move_all' state modifier). self._xys_at_press = self._xys.copy() @@ -3995,7 +4007,7 @@ def _onmove(self, event): self._xys[-1] = self._get_data_coords(event) # Move all vertices. - elif 'move_all' in self._state and self._eventpress: + elif 'move_all' in self._state and self._eventpress and self._selected: xdata, ydata = self._get_data_coords(event) dx = xdata - self._eventpress.xdata dy = ydata - self._eventpress.ydata @@ -4043,7 +4055,7 @@ def _on_key_release(self, event): self._xys.append(self._get_data_coords(event)) self._draw_polygon() # Reset the polygon if the released key is the 'clear' key. - elif event.key == self._state_modifier_keys.get('clear'): + elif self._selected and event.key == self._state_modifier_keys.get('clear'): event = self._clean_event(event) self._xys = [self._get_data_coords(event)] self._selection_completed = False @@ -4070,6 +4082,11 @@ def _draw_polygon(self): self._draw_polygon_without_update() self.update() + def _contains(self, event): + return mpl.path.Path(self.verts).contains_points( + [self._get_data_coords(event), ] + ) + @property def verts(self): """The polygon vertices, as a list of ``(x, y)`` pairs.""" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy