Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Change cursor when hovering over draggable artists #25412

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1298,6 +1298,9 @@ def __clear(self):
self.child_axes = []
self._current_image = None # strictly for pyplot via _sci, _gci
self._projection_init = None # strictly for pyplot.subplot

if hasattr(self, "legend_") and self.legend_ is not None:
self.legend_.axes = self.legend_.figure = None
self.legend_ = None
self.containers = []

Expand Down
34 changes: 33 additions & 1 deletion lib/matplotlib/offsetbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import matplotlib.path as mpath
import matplotlib.text as mtext
import matplotlib.transforms as mtransforms
from matplotlib.backend_tools import Cursors
from matplotlib.font_manager import FontProperties
from matplotlib.image import BboxImage
from matplotlib.patches import (
Expand Down Expand Up @@ -1489,6 +1490,7 @@ def __init__(self, ref_artist, use_blit=False):
if not ref_artist.pickable():
ref_artist.set_picker(True)
self.got_artist = False
self._hover = False
self._use_blit = use_blit and self.canvas.supports_blit
callbacks = ref_artist.figure._canvas_callbacks
self._disconnectors = [
Expand All @@ -1508,7 +1510,33 @@ def __init__(self, ref_artist, use_blit=False):
disconnect.args[0] for disconnect in self._disconnectors[:2]])

def on_motion(self, evt):
if self._check_still_parented() and self.got_artist:
# Only check if the widget lock is available, setting it would prevent
# picking.
if not (
self._check_still_parented()
and self.canvas.widgetlock.available(self)
and self.ref_artist.pickable()
):
return
Comment on lines +1515 to +1520
Copy link
Member

@timhoffm timhoffm Aug 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the logic correct? If self.ref_artist.pickable() is False, we return. That means we never reach the original if self.got_artist: branch.


picker = self.ref_artist.get_picker()
if callable(picker):
inside, _ = picker(self, evt)
else:
inside, _ = self.ref_artist.contains(evt)

# If the mouse is moving quickly while dragging, it may leave the artist,
# but should still use the move cursor.
if inside or self.got_artist:
self._hover = True
self.canvas.set_cursor(Cursors.MOVE)
elif self._hover:
# Only change the cursor back if this is the widget that set it, to
# avoid multiple draggable widgets fighting over the cursor.
self._hover = False
self.canvas.set_cursor(Cursors.POINTER)

if self.got_artist:
dx = evt.x - self.mouse_x
dy = evt.y - self.mouse_y
self.update_offset(dx, dy)
Expand Down Expand Up @@ -1554,6 +1582,10 @@ def disconnect(self):
for disconnector in self._disconnectors:
disconnector()

if self._hover:
self._hover = False
self.canvas.set_cursor(Cursors.POINTER)

def save_offset(self):
pass

Expand Down
12 changes: 9 additions & 3 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8644,13 +8644,19 @@ def test_extent_units():

def test_cla_clears_children_axes_and_fig():
fig, ax = plt.subplots()
lines = ax.plot([], [], [], [])

lines = ax.plot([], [], [], [], label="line")
img = ax.imshow([[1]])
for art in lines + [img]:
legend = ax.legend()

children = [*lines, img, legend]

for art in children:
assert art.axes is ax
assert art.figure is fig

ax.clear()
for art in lines + [img]:
for art in children:
assert art.axes is None
assert art.figure is None

Expand Down