Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1859c81

Browse filesBrowse files
authored
Merge pull request #17135 from anntzer/panzoomhandler
Simplify pan/zoom toggling.
2 parents 32326fd + 2d41a72 commit 1859c81
Copy full SHA for 1859c81

File tree

Expand file treeCollapse file tree

4 files changed

+48
-64
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+48
-64
lines changed

‎lib/matplotlib/backend_bases.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backend_bases.py
+43-59Lines changed: 43 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"""
3030

3131
from contextlib import contextmanager
32-
from enum import IntEnum
32+
from enum import Enum, IntEnum
3333
import functools
3434
import importlib
3535
import io
@@ -2652,6 +2652,15 @@ def set_window_title(self, title):
26522652
cursors = tools.cursors
26532653

26542654

2655+
class _Mode(str, Enum):
2656+
NONE = ""
2657+
PAN = "pan/zoom"
2658+
ZOOM = "zoom rect"
2659+
2660+
def __str__(self):
2661+
return self.value
2662+
2663+
26552664
class NavigationToolbar2:
26562665
"""
26572666
Base class for the navigation cursor, version 2
@@ -2716,19 +2725,20 @@ def __init__(self, canvas):
27162725
canvas.toolbar = self
27172726
self._nav_stack = cbook.Stack()
27182727
self._xypress = None # location and axis info at the time of the press
2719-
self._idPress = None
2720-
self._idRelease = None
2721-
self._active = None
27222728
# This cursor will be set after the initial draw.
27232729
self._lastCursor = cursors.POINTER
27242730
self._init_toolbar()
2731+
self._id_press = self.canvas.mpl_connect(
2732+
'button_press_event', self._zoom_pan_handler)
2733+
self._id_release = self.canvas.mpl_connect(
2734+
'button_release_event', self._zoom_pan_handler)
27252735
self._id_drag = self.canvas.mpl_connect(
27262736
'motion_notify_event', self.mouse_move)
27272737
self._zoom_info = None
27282738

27292739
self._button_pressed = None # determined by button pressed at start
27302740

2731-
self.mode = '' # a mode string for the status bar
2741+
self.mode = _Mode.NONE # a mode string for the status bar
27322742
self.set_history_buttons()
27332743

27342744
def set_message(self, s):
@@ -2806,17 +2816,17 @@ def _update_cursor(self, event):
28062816
"""
28072817
Update the cursor after a mouse move event or a tool (de)activation.
28082818
"""
2809-
if not event.inaxes or not self._active:
2819+
if not event.inaxes or not self.mode:
28102820
if self._lastCursor != cursors.POINTER:
28112821
self.set_cursor(cursors.POINTER)
28122822
self._lastCursor = cursors.POINTER
28132823
else:
2814-
if (self._active == 'ZOOM'
2824+
if (self.mode == _Mode.ZOOM
28152825
and self._lastCursor != cursors.SELECT_REGION):
28162826
self.set_cursor(cursors.SELECT_REGION)
28172827
self._lastCursor = cursors.SELECT_REGION
2818-
elif (self._active == 'PAN' and
2819-
self._lastCursor != cursors.MOVE):
2828+
elif (self.mode == _Mode.PAN
2829+
and self._lastCursor != cursors.MOVE):
28202830
self.set_cursor(cursors.MOVE)
28212831
self._lastCursor = cursors.MOVE
28222832

@@ -2871,40 +2881,32 @@ def mouse_move(self, event):
28712881
else:
28722882
self.set_message(self.mode)
28732883

2884+
def _zoom_pan_handler(self, event):
2885+
if self.mode == _Mode.PAN:
2886+
if event.name == "button_press_event":
2887+
self.press_pan(event)
2888+
elif event.name == "button_release_event":
2889+
self.release_pan(event)
2890+
if self.mode == _Mode.ZOOM:
2891+
if event.name == "button_press_event":
2892+
self.press_zoom(event)
2893+
elif event.name == "button_release_event":
2894+
self.release_zoom(event)
2895+
28742896
def pan(self, *args):
28752897
"""
2876-
Activate the pan/zoom tool.
2898+
Toggle the pan/zoom tool.
28772899
28782900
Pan with left button, zoom with right.
28792901
"""
2880-
# set the pointer icon and button press funcs to the
2881-
# appropriate callbacks
2882-
2883-
if self._active == 'PAN':
2884-
self._active = None
2902+
if self.mode == _Mode.PAN:
2903+
self.mode = _Mode.NONE
2904+
self.canvas.widgetlock.release(self)
28852905
else:
2886-
self._active = 'PAN'
2887-
if self._idPress is not None:
2888-
self._idPress = self.canvas.mpl_disconnect(self._idPress)
2889-
self.mode = ''
2890-
2891-
if self._idRelease is not None:
2892-
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
2893-
self.mode = ''
2894-
2895-
if self._active:
2896-
self._idPress = self.canvas.mpl_connect(
2897-
'button_press_event', self.press_pan)
2898-
self._idRelease = self.canvas.mpl_connect(
2899-
'button_release_event', self.release_pan)
2900-
self.mode = 'pan/zoom'
2906+
self.mode = _Mode.PAN
29012907
self.canvas.widgetlock(self)
2902-
else:
2903-
self.canvas.widgetlock.release(self)
2904-
29052908
for a in self.canvas.figure.get_axes():
2906-
a.set_navigate_mode(self._active)
2907-
2909+
a.set_navigate_mode(self.mode)
29082910
self.set_message(self.mode)
29092911

29102912
def press(self, event):
@@ -3108,33 +3110,15 @@ def update(self):
31083110
self.set_history_buttons()
31093111

31103112
def zoom(self, *args):
3111-
"""Activate zoom to rect mode."""
3112-
if self._active == 'ZOOM':
3113-
self._active = None
3113+
"""Toggle zoom to rect mode."""
3114+
if self.mode == _Mode.ZOOM:
3115+
self.mode = _Mode.NONE
3116+
self.canvas.widgetlock.release(self)
31143117
else:
3115-
self._active = 'ZOOM'
3116-
3117-
if self._idPress is not None:
3118-
self._idPress = self.canvas.mpl_disconnect(self._idPress)
3119-
self.mode = ''
3120-
3121-
if self._idRelease is not None:
3122-
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
3123-
self.mode = ''
3124-
3125-
if self._active:
3126-
self._idPress = self.canvas.mpl_connect('button_press_event',
3127-
self.press_zoom)
3128-
self._idRelease = self.canvas.mpl_connect('button_release_event',
3129-
self.release_zoom)
3130-
self.mode = 'zoom rect'
3118+
self.mode = _Mode.ZOOM
31313119
self.canvas.widgetlock(self)
3132-
else:
3133-
self.canvas.widgetlock.release(self)
3134-
31353120
for a in self.canvas.figure.get_axes():
3136-
a.set_navigate_mode(self._active)
3137-
3121+
a.set_navigate_mode(self.mode)
31383122
self.set_message(self.mode)
31393123

31403124
def set_history_buttons(self):

‎lib/matplotlib/backends/backend_gtk3.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_gtk3.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ def _update_buttons_checked(self):
528528
button = self._gtk_ids.get(name)
529529
if button:
530530
with button.handler_block(button._signal_handler):
531-
button.set_active(self._active == active)
531+
button.set_active(self.mode.name == active)
532532

533533
def pan(self, *args):
534534
super().pan(*args)

‎lib/matplotlib/backends/backend_qt5.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_qt5.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -745,9 +745,9 @@ def edit_parameters(self):
745745
def _update_buttons_checked(self):
746746
# sync button checkstates to match active mode
747747
if 'pan' in self._actions:
748-
self._actions['pan'].setChecked(self._active == 'PAN')
748+
self._actions['pan'].setChecked(self.mode.name == 'PAN')
749749
if 'zoom' in self._actions:
750-
self._actions['zoom'].setChecked(self._active == 'ZOOM')
750+
self._actions['zoom'].setChecked(self.mode.name == 'ZOOM')
751751

752752
def pan(self, *args):
753753
super().pan(*args)

‎lib/matplotlib/backends/backend_wx.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_wx.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ def set_cursor(self, cursor):
12091209
self.canvas.Update()
12101210

12111211
def press(self, event):
1212-
if self._active == 'ZOOM':
1212+
if self.mode.name == 'ZOOM':
12131213
if not self.retinaFix:
12141214
self.wxoverlay = wx.Overlay()
12151215
else:
@@ -1221,7 +1221,7 @@ def press(self, event):
12211221
self.zoomAxes = event.inaxes
12221222

12231223
def release(self, event):
1224-
if self._active == 'ZOOM':
1224+
if self.mode.name == 'ZOOM':
12251225
# When the mouse is released we reset the overlay and it
12261226
# restores the former content to the window.
12271227
if not self.retinaFix:

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.