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

Skip to content

Commit ea4274e

Browse files
authored
Merge pull request #6498 from anntzer/artist-contains-checks-canvas-identity
Check canvas identity in Artist.contains.
2 parents f529ced + 14ec7d7 commit ea4274e

13 files changed

+82
-31
lines changed

lib/matplotlib/artist.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,32 @@ def get_children(self):
381381
r"""Return a list of the child `.Artist`\s of this `.Artist`."""
382382
return []
383383

384+
def _default_contains(self, mouseevent, figure=None):
385+
"""
386+
Base impl. for checking whether a mouseevent happened in an artist.
387+
388+
1. If the artist defines a custom checker, use it.
389+
2. If the artist figure is known and the event did not occur in that
390+
figure (by checking its ``canvas`` attribute), reject it.
391+
3. Otherwise, return `None, {}`, indicating that the subclass'
392+
implementation should be used.
393+
394+
Subclasses should start their definition of `contains` as follows:
395+
396+
inside, info = self._default_contains(mouseevent)
397+
if inside is not None:
398+
return inside, info
399+
# subclass-specific implementation follows
400+
401+
The `canvas` kwarg is provided for the implementation of
402+
`Figure.contains`.
403+
"""
404+
if callable(self._contains):
405+
return self._contains(self, mouseevent)
406+
if figure is not None and mouseevent.canvas is not figure.canvas:
407+
return False, {}
408+
return None, {}
409+
384410
def contains(self, mouseevent):
385411
"""Test whether the artist contains the mouse event.
386412
@@ -401,8 +427,9 @@ def contains(self, mouseevent):
401427
--------
402428
set_contains, get_contains
403429
"""
404-
if self._contains is not None:
405-
return self._contains(self, mouseevent)
430+
inside, info = self._default_contains(mouseevent)
431+
if inside is not None:
432+
return inside, info
406433
_log.warning("%r needs 'contains' method", self.__class__.__name__)
407434
return False, {}
408435

lib/matplotlib/axes/_base.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4200,8 +4200,9 @@ def get_children(self):
42004200

42014201
def contains(self, mouseevent):
42024202
# docstring inherited.
4203-
if self._contains is not None:
4204-
return self._contains(self, mouseevent)
4203+
inside, info = self._default_contains(mouseevent)
4204+
if inside is not None:
4205+
return inside, info
42054206
return self.patch.contains(mouseevent)
42064207

42074208
def contains_point(self, point):

lib/matplotlib/axis.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,9 @@ def contains(self, mouseevent):
242242
This function always returns false. It is more useful to test if the
243243
axis as a whole contains the mouse rather than the set of tick marks.
244244
"""
245-
if self._contains is not None:
246-
return self._contains(self, mouseevent)
245+
inside, info = self._default_contains(mouseevent)
246+
if inside is not None:
247+
return inside, info
247248
return False, {}
248249

249250
def set_pad(self, val):
@@ -1923,8 +1924,9 @@ class XAxis(Axis):
19231924
def contains(self, mouseevent):
19241925
"""Test whether the mouse event occurred in the x axis.
19251926
"""
1926-
if self._contains is not None:
1927-
return self._contains(self, mouseevent)
1927+
inside, info = self._default_contains(mouseevent)
1928+
if inside is not None:
1929+
return inside, info
19281930

19291931
x, y = mouseevent.x, mouseevent.y
19301932
try:
@@ -2208,8 +2210,9 @@ def contains(self, mouseevent):
22082210
22092211
Returns *True* | *False*
22102212
"""
2211-
if self._contains is not None:
2212-
return self._contains(self, mouseevent)
2213+
inside, info = self._default_contains(mouseevent)
2214+
if inside is not None:
2215+
return inside, info
22132216

22142217
x, y = mouseevent.x, mouseevent.y
22152218
try:

lib/matplotlib/collections.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,9 @@ def contains(self, mouseevent):
352352
Returns ``bool, dict(ind=itemlist)``, where every item in itemlist
353353
contains the event.
354354
"""
355-
if self._contains is not None:
356-
return self._contains(self, mouseevent)
355+
inside, info = self._default_contains(mouseevent)
356+
if inside is not None:
357+
return inside, info
357358

358359
if not self.get_visible():
359360
return False, {}

lib/matplotlib/figure.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,9 @@ def contains(self, mouseevent):
671671
-------
672672
bool, {}
673673
"""
674-
if self._contains is not None:
675-
return self._contains(self, mouseevent)
674+
inside, info = self._default_contains(mouseevent, figure=self)
675+
if inside is not None:
676+
return inside, info
676677
inside = self.bbox.contains(mouseevent.x, mouseevent.y)
677678
return inside, {}
678679

lib/matplotlib/image.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,9 @@ def contains(self, mouseevent):
589589
"""
590590
Test whether the mouse event occurred within the image.
591591
"""
592-
if self._contains is not None:
593-
return self._contains(self, mouseevent)
592+
inside, info = self._default_contains(mouseevent)
593+
if inside is not None:
594+
return inside, info
594595
# 1) This doesn't work for figimage; but figimage also needs a fix
595596
# below (as the check cannot use x/ydata and extents).
596597
# 2) As long as the check below uses x/ydata, we need to test axes
@@ -1299,8 +1300,9 @@ def get_window_extent(self, renderer=None):
12991300

13001301
def contains(self, mouseevent):
13011302
"""Test whether the mouse event occurred within the image."""
1302-
if self._contains is not None:
1303-
return self._contains(self, mouseevent)
1303+
inside, info = self._default_contains(mouseevent)
1304+
if inside is not None:
1305+
return inside, info
13041306

13051307
if not self.get_visible(): # or self.get_figure()._renderer is None:
13061308
return False, {}

lib/matplotlib/legend.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,9 @@ def _find_best_position(self, width, height, renderer, consider=None):
11481148
return l, b
11491149

11501150
def contains(self, event):
1151+
inside, info = self._default_contains(event)
1152+
if inside is not None:
1153+
return inside, info
11511154
return self.legendPatch.contains(event)
11521155

11531156
def set_draggable(self, state, use_blit=False, update='loc'):

lib/matplotlib/lines.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,9 @@ def contains(self, mouseevent):
446446
447447
TODO: sort returned indices by distance
448448
"""
449-
if callable(self._contains):
450-
return self._contains(self, mouseevent)
449+
inside, info = self._default_contains(mouseevent)
450+
if inside is not None:
451+
return inside, info
451452

452453
if not isinstance(self.pickradius, Number):
453454
raise ValueError("pick radius should be a distance")

lib/matplotlib/offsetbox.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,9 @@ def contains(self, mouseevent):
228228
--------
229229
.Artist.contains
230230
"""
231+
inside, info = self._default_contains(mouseevent)
232+
if inside is not None:
233+
return inside, info
231234
for c in self.get_children():
232235
a, b = c.contains(mouseevent)
233236
if a:
@@ -1556,8 +1559,11 @@ def anncoords(self, coords):
15561559
self.boxcoords = coords
15571560
self.stale = True
15581561

1559-
def contains(self, event):
1560-
t, tinfo = self.offsetbox.contains(event)
1562+
def contains(self, mouseevent):
1563+
inside, info = self._default_contains(mouseevent)
1564+
if inside is not None:
1565+
return inside, info
1566+
t, tinfo = self.offsetbox.contains(mouseevent)
15611567
#if self.arrow_patch is not None:
15621568
# a, ainfo=self.arrow_patch.contains(event)
15631569
# t = t or a

lib/matplotlib/patches.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,9 @@ def contains(self, mouseevent, radius=None):
130130
-------
131131
(bool, empty dict)
132132
"""
133-
if self._contains is not None:
134-
return self._contains(self, mouseevent)
133+
inside, info = self._default_contains(mouseevent)
134+
if inside is not None:
135+
return inside, info
135136
radius = self._process_radius(radius)
136137
codes = self.get_path().codes
137138
if codes is not None:

lib/matplotlib/quiver.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,9 @@ def set_figure(self, fig):
369369
self.text.set_figure(fig)
370370

371371
def contains(self, mouseevent):
372+
inside, info = self._default_contains(mouseevent)
373+
if inside is not None:
374+
return inside, info
372375
# Maybe the dictionary should allow one to
373376
# distinguish between a text hit and a vector hit.
374377
if (self.text.contains(mouseevent)[0] or

lib/matplotlib/table.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -434,9 +434,9 @@ def _get_grid_bbox(self, renderer):
434434

435435
def contains(self, mouseevent):
436436
# docstring inherited
437-
if self._contains is not None:
438-
return self._contains(self, mouseevent)
439-
437+
inside, info = self._default_contains(mouseevent)
438+
if inside is not None:
439+
return inside, info
440440
# TODO: Return index of the cell containing the cursor so that the user
441441
# doesn't have to bind to each one individually.
442442
renderer = self.figure._cachedRenderer

lib/matplotlib/text.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,9 @@ def contains(self, mouseevent):
194194
-------
195195
bool : bool
196196
"""
197-
if self._contains is not None:
198-
return self._contains(self, mouseevent)
197+
inside, info = self._default_contains(mouseevent)
198+
if inside is not None:
199+
return inside, info
199200

200201
if not self.get_visible() or self._renderer is None:
201202
return False, {}
@@ -2180,8 +2181,9 @@ def transform(renderer) -> Transform
21802181
self.arrow_patch = None
21812182

21822183
def contains(self, event):
2183-
if self._contains is not None:
2184-
return self._contains(self, event)
2184+
inside, info = self._default_contains(event)
2185+
if inside is not None:
2186+
return inside, info
21852187
contains, tinfo = Text.contains(self, event)
21862188
if self.arrow_patch is not None:
21872189
in_patch, _ = self.arrow_patch.contains(event)

0 commit comments

Comments
 (0)