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

Skip to content

Commit 14ec7d7

Browse files
committed
Check canvas identity in Artist.contains.
1 parent 2d56d42 commit 14ec7d7

13 files changed

Lines changed: 82 additions & 31 deletions

File tree

lib/matplotlib/artist.py

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

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

lib/matplotlib/axes/_base.py

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

42204220
def contains(self, mouseevent):
42214221
# docstring inherited.
4222-
if self._contains is not None:
4223-
return self._contains(self, mouseevent)
4222+
inside, info = self._default_contains(mouseevent)
4223+
if inside is not None:
4224+
return inside, info
42244225
return self.patch.contains(mouseevent)
42254226

42264227
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
@@ -590,8 +590,9 @@ def contains(self, mouseevent):
590590
"""
591591
Test whether the mouse event occurred within the image.
592592
"""
593-
if self._contains is not None:
594-
return self._contains(self, mouseevent)
593+
inside, info = self._default_contains(mouseevent)
594+
if inside is not None:
595+
return inside, info
595596
# 1) This doesn't work for figimage; but figimage also needs a fix
596597
# below (as the check cannot use x/ydata and extents).
597598
# 2) As long as the check below uses x/ydata, we need to test axes
@@ -1300,8 +1301,9 @@ def get_window_extent(self, renderer=None):
13001301

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

13061308
if not self.get_visible(): # or self.get_figure()._renderer is None:
13071309
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:

0 commit comments

Comments
 (0)