|
29 | 29 | """ |
30 | 30 |
|
31 | 31 | from contextlib import contextmanager |
32 | | -from enum import IntEnum |
| 32 | +from enum import Enum, IntEnum |
33 | 33 | import functools |
34 | 34 | import importlib |
35 | 35 | import io |
@@ -2651,6 +2651,15 @@ def set_window_title(self, title): |
2651 | 2651 | cursors = tools.cursors |
2652 | 2652 |
|
2653 | 2653 |
|
| 2654 | +class _Mode(str, Enum): |
| 2655 | + NONE = "" |
| 2656 | + PAN = "pan/zoom" |
| 2657 | + ZOOM = "zoom rect" |
| 2658 | + |
| 2659 | + def __str__(self): |
| 2660 | + return self.value |
| 2661 | + |
| 2662 | + |
2654 | 2663 | class NavigationToolbar2: |
2655 | 2664 | """ |
2656 | 2665 | Base class for the navigation cursor, version 2 |
@@ -2715,19 +2724,20 @@ def __init__(self, canvas): |
2715 | 2724 | canvas.toolbar = self |
2716 | 2725 | self._nav_stack = cbook.Stack() |
2717 | 2726 | self._xypress = None # location and axis info at the time of the press |
2718 | | - self._idPress = None |
2719 | | - self._idRelease = None |
2720 | | - self._active = None |
2721 | 2727 | # This cursor will be set after the initial draw. |
2722 | 2728 | self._lastCursor = cursors.POINTER |
2723 | 2729 | self._init_toolbar() |
| 2730 | + self._id_press = self.canvas.mpl_connect( |
| 2731 | + 'button_press_event', self._zoom_pan_handler) |
| 2732 | + self._id_release = self.canvas.mpl_connect( |
| 2733 | + 'button_release_event', self._zoom_pan_handler) |
2724 | 2734 | self._id_drag = self.canvas.mpl_connect( |
2725 | 2735 | 'motion_notify_event', self.mouse_move) |
2726 | 2736 | self._zoom_info = None |
2727 | 2737 |
|
2728 | 2738 | self._button_pressed = None # determined by button pressed at start |
2729 | 2739 |
|
2730 | | - self.mode = '' # a mode string for the status bar |
| 2740 | + self.mode = _Mode.NONE # a mode string for the status bar |
2731 | 2741 | self.set_history_buttons() |
2732 | 2742 |
|
2733 | 2743 | def set_message(self, s): |
@@ -2805,17 +2815,17 @@ def _update_cursor(self, event): |
2805 | 2815 | """ |
2806 | 2816 | Update the cursor after a mouse move event or a tool (de)activation. |
2807 | 2817 | """ |
2808 | | - if not event.inaxes or not self._active: |
| 2818 | + if not event.inaxes or not self.mode: |
2809 | 2819 | if self._lastCursor != cursors.POINTER: |
2810 | 2820 | self.set_cursor(cursors.POINTER) |
2811 | 2821 | self._lastCursor = cursors.POINTER |
2812 | 2822 | else: |
2813 | | - if (self._active == 'ZOOM' |
| 2823 | + if (self.mode == _Mode.ZOOM |
2814 | 2824 | and self._lastCursor != cursors.SELECT_REGION): |
2815 | 2825 | self.set_cursor(cursors.SELECT_REGION) |
2816 | 2826 | self._lastCursor = cursors.SELECT_REGION |
2817 | | - elif (self._active == 'PAN' and |
2818 | | - self._lastCursor != cursors.MOVE): |
| 2827 | + elif (self.mode == _Mode.PAN |
| 2828 | + and self._lastCursor != cursors.MOVE): |
2819 | 2829 | self.set_cursor(cursors.MOVE) |
2820 | 2830 | self._lastCursor = cursors.MOVE |
2821 | 2831 |
|
@@ -2870,40 +2880,32 @@ def mouse_move(self, event): |
2870 | 2880 | else: |
2871 | 2881 | self.set_message(self.mode) |
2872 | 2882 |
|
| 2883 | + def _zoom_pan_handler(self, event): |
| 2884 | + if self.mode == _Mode.PAN: |
| 2885 | + if event.name == "button_press_event": |
| 2886 | + self.press_pan(event) |
| 2887 | + elif event.name == "button_release_event": |
| 2888 | + self.release_pan(event) |
| 2889 | + if self.mode == _Mode.ZOOM: |
| 2890 | + if event.name == "button_press_event": |
| 2891 | + self.press_zoom(event) |
| 2892 | + elif event.name == "button_release_event": |
| 2893 | + self.release_zoom(event) |
| 2894 | + |
2873 | 2895 | def pan(self, *args): |
2874 | 2896 | """ |
2875 | | - Activate the pan/zoom tool. |
| 2897 | + Toggle the pan/zoom tool. |
2876 | 2898 |
|
2877 | 2899 | Pan with left button, zoom with right. |
2878 | 2900 | """ |
2879 | | - # set the pointer icon and button press funcs to the |
2880 | | - # appropriate callbacks |
2881 | | - |
2882 | | - if self._active == 'PAN': |
2883 | | - self._active = None |
| 2901 | + if self.mode == _Mode.PAN: |
| 2902 | + self.mode = _Mode.NONE |
| 2903 | + self.canvas.widgetlock.release(self) |
2884 | 2904 | else: |
2885 | | - self._active = 'PAN' |
2886 | | - if self._idPress is not None: |
2887 | | - self._idPress = self.canvas.mpl_disconnect(self._idPress) |
2888 | | - self.mode = '' |
2889 | | - |
2890 | | - if self._idRelease is not None: |
2891 | | - self._idRelease = self.canvas.mpl_disconnect(self._idRelease) |
2892 | | - self.mode = '' |
2893 | | - |
2894 | | - if self._active: |
2895 | | - self._idPress = self.canvas.mpl_connect( |
2896 | | - 'button_press_event', self.press_pan) |
2897 | | - self._idRelease = self.canvas.mpl_connect( |
2898 | | - 'button_release_event', self.release_pan) |
2899 | | - self.mode = 'pan/zoom' |
| 2905 | + self.mode = _Mode.PAN |
2900 | 2906 | self.canvas.widgetlock(self) |
2901 | | - else: |
2902 | | - self.canvas.widgetlock.release(self) |
2903 | | - |
2904 | 2907 | for a in self.canvas.figure.get_axes(): |
2905 | | - a.set_navigate_mode(self._active) |
2906 | | - |
| 2908 | + a.set_navigate_mode(self.mode) |
2907 | 2909 | self.set_message(self.mode) |
2908 | 2910 |
|
2909 | 2911 | def press(self, event): |
@@ -3101,33 +3103,15 @@ def update(self): |
3101 | 3103 | self.set_history_buttons() |
3102 | 3104 |
|
3103 | 3105 | def zoom(self, *args): |
3104 | | - """Activate zoom to rect mode.""" |
3105 | | - if self._active == 'ZOOM': |
3106 | | - self._active = None |
| 3106 | + """Toggle zoom to rect mode.""" |
| 3107 | + if self.mode == _Mode.ZOOM: |
| 3108 | + self.mode = _Mode.NONE |
| 3109 | + self.canvas.widgetlock.release(self) |
3107 | 3110 | else: |
3108 | | - self._active = 'ZOOM' |
3109 | | - |
3110 | | - if self._idPress is not None: |
3111 | | - self._idPress = self.canvas.mpl_disconnect(self._idPress) |
3112 | | - self.mode = '' |
3113 | | - |
3114 | | - if self._idRelease is not None: |
3115 | | - self._idRelease = self.canvas.mpl_disconnect(self._idRelease) |
3116 | | - self.mode = '' |
3117 | | - |
3118 | | - if self._active: |
3119 | | - self._idPress = self.canvas.mpl_connect('button_press_event', |
3120 | | - self.press_zoom) |
3121 | | - self._idRelease = self.canvas.mpl_connect('button_release_event', |
3122 | | - self.release_zoom) |
3123 | | - self.mode = 'zoom rect' |
| 3111 | + self.mode = _Mode.ZOOM |
3124 | 3112 | self.canvas.widgetlock(self) |
3125 | | - else: |
3126 | | - self.canvas.widgetlock.release(self) |
3127 | | - |
3128 | 3113 | for a in self.canvas.figure.get_axes(): |
3129 | | - a.set_navigate_mode(self._active) |
3130 | | - |
| 3114 | + a.set_navigate_mode(self.mode) |
3131 | 3115 | self.set_message(self.mode) |
3132 | 3116 |
|
3133 | 3117 | def set_history_buttons(self): |
|
0 commit comments