@@ -1220,11 +1220,16 @@ class Event:
12201220 guiEvent
12211221 The GUI event that triggered the Matplotlib event.
12221222 """
1223+
12231224 def __init__ (self , name , canvas , guiEvent = None ):
12241225 self .name = name
12251226 self .canvas = canvas
12261227 self .guiEvent = guiEvent
12271228
1229+ def _process (self ):
1230+ """Generate an event with name ``self.name`` on ``self.canvas``."""
1231+ self .canvas .callbacks .process (self .name , self )
1232+
12281233
12291234class DrawEvent (Event ):
12301235 """
@@ -1267,6 +1272,7 @@ class ResizeEvent(Event):
12671272 height : int
12681273 Height of the canvas in pixels.
12691274 """
1275+
12701276 def __init__ (self , name , canvas ):
12711277 super ().__init__ (name , canvas )
12721278 self .width , self .height = canvas .get_width_height ()
@@ -1294,7 +1300,7 @@ class LocationEvent(Event):
12941300 is not over an Axes.
12951301 """
12961302
1297- lastevent = None # the last event that was triggered before this one
1303+ lastevent = None # The last event processed so far.
12981304
12991305 def __init__ (self , name , canvas , x , y , guiEvent = None ):
13001306 super ().__init__ (name , canvas , guiEvent = guiEvent )
@@ -1308,7 +1314,6 @@ def __init__(self, name, canvas, x, y, guiEvent=None):
13081314
13091315 if x is None or y is None :
13101316 # cannot check if event was in Axes if no (x, y) info
1311- self ._update_enter_leave ()
13121317 return
13131318
13141319 if self .canvas .mouse_grabber is None :
@@ -1326,34 +1331,6 @@ def __init__(self, name, canvas, x, y, guiEvent=None):
13261331 self .xdata = xdata
13271332 self .ydata = ydata
13281333
1329- self ._update_enter_leave ()
1330-
1331- def _update_enter_leave (self ):
1332- """Process the figure/axes enter leave events."""
1333- if LocationEvent .lastevent is not None :
1334- last = LocationEvent .lastevent
1335- if last .inaxes != self .inaxes :
1336- # process Axes enter/leave events
1337- try :
1338- if last .inaxes is not None :
1339- last .canvas .callbacks .process ('axes_leave_event' , last )
1340- except Exception :
1341- pass
1342- # See ticket 2901582.
1343- # I think this is a valid exception to the rule
1344- # against catching all exceptions; if anything goes
1345- # wrong, we simply want to move on and process the
1346- # current event.
1347- if self .inaxes is not None :
1348- self .canvas .callbacks .process ('axes_enter_event' , self )
1349-
1350- else :
1351- # process a figure enter event
1352- if self .inaxes is not None :
1353- self .canvas .callbacks .process ('axes_enter_event' , self )
1354-
1355- LocationEvent .lastevent = self
1356-
13571334
13581335class MouseButton (IntEnum ):
13591336 LEFT = 1
@@ -1375,11 +1352,15 @@ class MouseEvent(LocationEvent):
13751352 ----------
13761353 button : None or `MouseButton` or {'up', 'down'}
13771354 The button pressed. 'up' and 'down' are used for scroll events.
1355+
13781356 Note that LEFT and RIGHT actually refer to the "primary" and
13791357 "secondary" buttons, i.e. if the user inverts their left and right
13801358 buttons ("left-handed setting") then the LEFT button will be the one
13811359 physically on the right.
13821360
1361+ If this is unset, *name* is "scroll_event", and *step* is nonzero, then
1362+ this will be set to "up" or "down" depending on the sign of *step*.
1363+
13831364 key : None or str
13841365 The key pressed when the mouse event triggered, e.g. 'shift'.
13851366 See `KeyEvent`.
@@ -1411,17 +1392,19 @@ def on_press(event):
14111392
14121393 def __init__ (self , name , canvas , x , y , button = None , key = None ,
14131394 step = 0 , dblclick = False , guiEvent = None ):
1395+ super ().__init__ (name , canvas , x , y , guiEvent = guiEvent )
14141396 if button in MouseButton .__members__ .values ():
14151397 button = MouseButton (button )
1398+ if name == "scroll_event" and button is None :
1399+ if step > 0 :
1400+ button = "up"
1401+ elif step < 0 :
1402+ button = "down"
14161403 self .button = button
14171404 self .key = key
14181405 self .step = step
14191406 self .dblclick = dblclick
14201407
1421- # super-init is deferred to the end because it calls back on
1422- # 'axes_enter_event', which requires a fully initialized event.
1423- super ().__init__ (name , canvas , x , y , guiEvent = guiEvent )
1424-
14251408 def __str__ (self ):
14261409 return (f"{ self .name } : "
14271410 f"xy=({ self .x } , { self .y } ) xydata=({ self .xdata } , { self .ydata } ) "
@@ -1467,8 +1450,11 @@ def on_pick(event):
14671450
14681451 cid = fig.canvas.mpl_connect('pick_event', on_pick)
14691452 """
1453+
14701454 def __init__ (self , name , canvas , mouseevent , artist ,
14711455 guiEvent = None , ** kwargs ):
1456+ if guiEvent is None :
1457+ guiEvent = mouseevent .guiEvent
14721458 super ().__init__ (name , canvas , guiEvent )
14731459 self .mouseevent = mouseevent
14741460 self .artist = artist
@@ -1506,10 +1492,46 @@ def on_key(event):
15061492
15071493 cid = fig.canvas.mpl_connect('key_press_event', on_key)
15081494 """
1495+
15091496 def __init__ (self , name , canvas , key , x = 0 , y = 0 , guiEvent = None ):
1510- self .key = key
1511- # super-init deferred to the end: callback errors if called before
15121497 super ().__init__ (name , canvas , x , y , guiEvent = guiEvent )
1498+ self .key = key
1499+
1500+
1501+ # Default callback for key events.
1502+ def _key_handler (event ):
1503+ # Dead reckoning of key.
1504+ if event .name == "key_press_event" :
1505+ event .canvas ._key = event .key
1506+ elif event .name == "key_release_event" :
1507+ event .canvas ._key = None
1508+
1509+
1510+ # Default callback for mouse events.
1511+ def _mouse_handler (event ):
1512+ # Dead-reckoning of button and key.
1513+ if event .name == "button_press_event" :
1514+ event .canvas ._button = event .button
1515+ elif event .name == "button_release_event" :
1516+ event .canvas ._button = None
1517+ elif event .name == "motion_notify_event" and event .button is None :
1518+ event .button = event .canvas ._button
1519+ if event .key is None :
1520+ event .key = event .canvas ._key
1521+ # Emit axes_enter/axes_leave.
1522+ if event .name == "motion_notify_event" :
1523+ last = LocationEvent .lastevent
1524+ last_axes = last .inaxes if last is not None else None
1525+ if last_axes != event .inaxes :
1526+ if last_axes is not None :
1527+ try :
1528+ last .canvas .callbacks .process ("axes_leave_event" , last )
1529+ except Exception :
1530+ pass # The last canvas may already have been torn down.
1531+ if event .inaxes is not None :
1532+ event .canvas .callbacks .process ("axes_enter_event" , event )
1533+ LocationEvent .lastevent = (
1534+ None if event .name == "figure_leave_event" else event )
15131535
15141536
15151537def _get_renderer (figure , print_method = None ):
@@ -1720,12 +1742,16 @@ def resize(self, w, h):
17201742 _api .warn_deprecated ("3.6" , name = "resize" , obj_type = "method" ,
17211743 alternative = "FigureManagerBase.resize" )
17221744
1745+ @_api .deprecated ("3.6" , alternative = (
1746+ "callbacks.process('draw_event', DrawEvent(...))" ))
17231747 def draw_event (self , renderer ):
17241748 """Pass a `DrawEvent` to all functions connected to ``draw_event``."""
17251749 s = 'draw_event'
17261750 event = DrawEvent (s , self , renderer )
17271751 self .callbacks .process (s , event )
17281752
1753+ @_api .deprecated ("3.6" , alternative = (
1754+ "callbacks.process('resize_event', ResizeEvent(...))" ))
17291755 def resize_event (self ):
17301756 """
17311757 Pass a `ResizeEvent` to all functions connected to ``resize_event``.
@@ -1735,6 +1761,8 @@ def resize_event(self):
17351761 self .callbacks .process (s , event )
17361762 self .draw_idle ()
17371763
1764+ @_api .deprecated ("3.6" , alternative = (
1765+ "callbacks.process('close_event', CloseEvent(...))" ))
17381766 def close_event (self , guiEvent = None ):
17391767 """
17401768 Pass a `CloseEvent` to all functions connected to ``close_event``.
@@ -1751,6 +1779,8 @@ def close_event(self, guiEvent=None):
17511779 # AttributeError occurs on OSX with qt4agg upon exiting
17521780 # with an open window; 'callbacks' attribute no longer exists.
17531781
1782+ @_api .deprecated ("3.6" , alternative = (
1783+ "callbacks.process('key_press_event', KeyEvent(...))" ))
17541784 def key_press_event (self , key , guiEvent = None ):
17551785 """
17561786 Pass a `KeyEvent` to all functions connected to ``key_press_event``.
@@ -1761,6 +1791,8 @@ def key_press_event(self, key, guiEvent=None):
17611791 s , self , key , self ._lastx , self ._lasty , guiEvent = guiEvent )
17621792 self .callbacks .process (s , event )
17631793
1794+ @_api .deprecated ("3.6" , alternative = (
1795+ "callbacks.process('key_release_event', KeyEvent(...))" ))
17641796 def key_release_event (self , key , guiEvent = None ):
17651797 """
17661798 Pass a `KeyEvent` to all functions connected to ``key_release_event``.
@@ -1771,6 +1803,8 @@ def key_release_event(self, key, guiEvent=None):
17711803 self .callbacks .process (s , event )
17721804 self ._key = None
17731805
1806+ @_api .deprecated ("3.6" , alternative = (
1807+ "callbacks.process('pick_event', PickEvent(...))" ))
17741808 def pick_event (self , mouseevent , artist , ** kwargs ):
17751809 """
17761810 Callback processing for pick events.
@@ -1787,6 +1821,8 @@ def pick_event(self, mouseevent, artist, **kwargs):
17871821 ** kwargs )
17881822 self .callbacks .process (s , event )
17891823
1824+ @_api .deprecated ("3.6" , alternative = (
1825+ "callbacks.process('scroll_event', MouseEvent(...))" ))
17901826 def scroll_event (self , x , y , step , guiEvent = None ):
17911827 """
17921828 Callback processing for scroll events.
@@ -1807,6 +1843,8 @@ def scroll_event(self, x, y, step, guiEvent=None):
18071843 step = step , guiEvent = guiEvent )
18081844 self .callbacks .process (s , mouseevent )
18091845
1846+ @_api .deprecated ("3.6" , alternative = (
1847+ "callbacks.process('button_press_event', MouseEvent(...))" ))
18101848 def button_press_event (self , x , y , button , dblclick = False , guiEvent = None ):
18111849 """
18121850 Callback processing for mouse button press events.
@@ -1824,6 +1862,8 @@ def button_press_event(self, x, y, button, dblclick=False, guiEvent=None):
18241862 dblclick = dblclick , guiEvent = guiEvent )
18251863 self .callbacks .process (s , mouseevent )
18261864
1865+ @_api .deprecated ("3.6" , alternative = (
1866+ "callbacks.process('button_release_event', MouseEvent(...))" ))
18271867 def button_release_event (self , x , y , button , guiEvent = None ):
18281868 """
18291869 Callback processing for mouse button release events.
@@ -1848,6 +1888,9 @@ def button_release_event(self, x, y, button, guiEvent=None):
18481888 self .callbacks .process (s , event )
18491889 self ._button = None
18501890
1891+ # Also remove _lastx, _lasty when this goes away.
1892+ @_api .deprecated ("3.6" , alternative = (
1893+ "callbacks.process('motion_notify_event', MouseEvent(...))" ))
18511894 def motion_notify_event (self , x , y , guiEvent = None ):
18521895 """
18531896 Callback processing for mouse movement events.
@@ -1873,6 +1916,8 @@ def motion_notify_event(self, x, y, guiEvent=None):
18731916 guiEvent = guiEvent )
18741917 self .callbacks .process (s , event )
18751918
1919+ @_api .deprecated ("3.6" , alternative = (
1920+ "callbacks.process('leave_notify_event', LocationEvent(...))" ))
18761921 def leave_notify_event (self , guiEvent = None ):
18771922 """
18781923 Callback processing for the mouse cursor leaving the canvas.
@@ -1889,6 +1934,8 @@ def leave_notify_event(self, guiEvent=None):
18891934 LocationEvent .lastevent = None
18901935 self ._lastx , self ._lasty = None , None
18911936
1937+ @_api .deprecated ("3.6" , alternative = (
1938+ "callbacks.process('enter_notify_event', LocationEvent(...))" ))
18921939 def enter_notify_event (self , guiEvent = None , xy = None ):
18931940 """
18941941 Callback processing for the mouse cursor entering the canvas.
0 commit comments