From c2d4061d483252943fd8e8a59176a2a428be29b3 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 24 Jul 2021 05:26:54 -0400 Subject: [PATCH 1/2] Clear the selector's active handle on button release. --- lib/matplotlib/widgets.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/matplotlib/widgets.py b/lib/matplotlib/widgets.py index 6943f2a4b7d8..32c0e3ca49f1 100644 --- a/lib/matplotlib/widgets.py +++ b/lib/matplotlib/widgets.py @@ -2264,6 +2264,8 @@ def _release(self, event): # self._pressv is deprecated but we still need to maintain it self._pressv = None + self._active_handle = None + return False def _onmove(self, event): @@ -2805,6 +2807,7 @@ def _release(self, event): # call desired function self.onselect(self._eventpress, self._eventrelease) self.update() + self._active_handle = None return False From e6176b74e8337de9aee8c20388fab54026e639e3 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 24 Jul 2021 05:30:13 -0400 Subject: [PATCH 2/2] Set the canvas cursor when using a SpanSelector. This sets either a horizontal or vertcal resize cursor when initiating a selection, moving the span, or when hovering over an end handle. --- lib/matplotlib/widgets.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/widgets.py b/lib/matplotlib/widgets.py index 32c0e3ca49f1..010fd04fd798 100644 --- a/lib/matplotlib/widgets.py +++ b/lib/matplotlib/widgets.py @@ -17,7 +17,7 @@ import matplotlib as mpl from matplotlib import docstring -from . import _api, cbook, colors, ticker +from . import _api, backend_tools, cbook, colors, ticker from .lines import Line2D from .patches import Circle, Rectangle, Ellipse @@ -2192,8 +2192,26 @@ def _setup_edge_handle(self, props): useblit=self.useblit) self.artists.extend([line for line in self._edge_handles.artists]) + def _set_cursor(self, enabled): + """Update the canvas cursor based on direction of the selector.""" + if enabled: + cursor = (backend_tools.Cursors.RESIZE_HORIZONTAL + if self.direction == 'horizontal' else + backend_tools.Cursors.RESIZE_VERTICAL) + else: + cursor = backend_tools.Cursors.POINTER + + self.ax.figure.canvas.set_cursor(cursor) + + def connect_default_events(self): + # docstring inherited + super().connect_default_events() + if getattr(self, '_interactive', False): + self.connect_event('motion_notify_event', self._hover) + def _press(self, event): """Button press event handler.""" + self._set_cursor(True) if self._interactive and self._rect.get_visible(): self._set_active_handle(event) else: @@ -2248,6 +2266,7 @@ def direction(self, direction): def _release(self, event): """Button release event handler.""" + self._set_cursor(False) if not self._interactive: self._rect.set_visible(False) @@ -2268,6 +2287,19 @@ def _release(self, event): return False + def _hover(self, event): + """Update the canvas cursor if it's over a handle.""" + if self.ignore(event): + return + + if self._active_handle is not None: + # Do nothing if button is pressed and a handle is active, which may + # occur with drag_from_anywhere=True. + return + + _, e_dist = self._edge_handles.closest(event.x, event.y) + self._set_cursor(e_dist <= self.grab_range) + def _onmove(self, event): """Motion notify event handler."""