From 0ff1924e36082718f77919c91ecaa8dce14dda29 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Sun, 25 Nov 2018 22:20:54 +0100 Subject: [PATCH] Support forward/backward mouse buttons --- doc/users/next_whats_new/2019-02-17-TH.rst | 9 ++++++ lib/matplotlib/backend_bases.py | 37 ++++++++++++++++++++-- lib/matplotlib/backends/backend_qt5.py | 12 +++---- lib/matplotlib/rcsetup.py | 6 ++-- matplotlibrc.template | 4 +-- 5 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 doc/users/next_whats_new/2019-02-17-TH.rst diff --git a/doc/users/next_whats_new/2019-02-17-TH.rst b/doc/users/next_whats_new/2019-02-17-TH.rst new file mode 100644 index 000000000000..e2a31472bdb6 --- /dev/null +++ b/doc/users/next_whats_new/2019-02-17-TH.rst @@ -0,0 +1,9 @@ +Support for forward/backward mouse buttons +`````````````````````````````````````````` + +Figure managers now support a ``button_press`` event for mouse buttons, similar +to the ``key_press`` events. This allows binding actions to mouse buttons (see +`.MouseButton`). + +The first application of this mechanism is support of forward/backward mouse +buttons in figures created with the Qt5 backend. \ No newline at end of file diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index bf579ae71b5b..3de25e400e27 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -1367,6 +1367,8 @@ class MouseButton(IntEnum): LEFT = 1 MIDDLE = 2 RIGHT = 3 + BACK = 8 + FORWARD = 9 class MouseEvent(LocationEvent): @@ -2386,6 +2388,18 @@ def _get_uniform_gridstate(ticks): a.set_navigate(i == n) +def button_press_handler(event, canvas, toolbar=None): + """ + The default Matplotlib button actions for extra mouse buttons. + """ + if toolbar is not None: + button_name = str(MouseButton(event.button)) + if button_name in rcParams['keymap.back']: + toolbar.back() + elif button_name in rcParams['keymap.forward']: + toolbar.forward() + + class NonGuiException(Exception): pass @@ -2403,11 +2417,19 @@ class FigureManagerBase(object): The figure number key_press_handler_id : int - The default key handler cid, when using the toolmanager. Can be used - to disable default key press handling :: + The default key handler cid, when using the toolmanager. + To disable the default key press handling use:: figure.canvas.mpl_disconnect( figure.canvas.manager.key_press_handler_id) + + button_press_handler_id : int + The default mouse button handler cid, when using the toolmanager. + To disable the default button press handling use:: + + figure.canvas.mpl_disconnect( + figure.canvas.manager.button_press_handler_id) + """ def __init__(self, canvas, num): self.canvas = canvas @@ -2415,10 +2437,14 @@ def __init__(self, canvas, num): self.num = num self.key_press_handler_id = None + self.button_press_handler_id = None if rcParams['toolbar'] != 'toolmanager': self.key_press_handler_id = self.canvas.mpl_connect( 'key_press_event', self.key_press) + self.button_press_handler_id = self.canvas.mpl_connect( + 'button_press_event', + self.button_press) self.toolmanager = None self.toolbar = None @@ -2455,6 +2481,13 @@ def key_press(self, event): if rcParams['toolbar'] != 'toolmanager': key_press_handler(event, self.canvas, self.canvas.toolbar) + def button_press(self, event): + """ + The default Matplotlib button actions for extra mouse buttons. + """ + if rcParams['toolbar'] != 'toolmanager': + button_press_handler(event, self.canvas, self.canvas.toolbar) + def get_window_title(self): """Get the title text of the window containing the figure. diff --git a/lib/matplotlib/backends/backend_qt5.py b/lib/matplotlib/backends/backend_qt5.py index f6a9306f54f2..d6707946e1fd 100644 --- a/lib/matplotlib/backends/backend_qt5.py +++ b/lib/matplotlib/backends/backend_qt5.py @@ -11,7 +11,7 @@ from matplotlib._pylab_helpers import Gcf from matplotlib.backend_bases import ( _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2, - TimerBase, cursors, ToolContainerBase, StatusbarBase) + TimerBase, cursors, ToolContainerBase, StatusbarBase, MouseButton) import matplotlib.backends.qt_editor.figureoptions as figureoptions from matplotlib.backends.qt_editor.formsubplottool import UiSubplotTool from matplotlib.backend_managers import ToolManager @@ -213,11 +213,11 @@ def _timer_stop(self): class FigureCanvasQT(QtWidgets.QWidget, FigureCanvasBase): # map Qt button codes to MouseEvent's ones: - buttond = {QtCore.Qt.LeftButton: 1, - QtCore.Qt.MidButton: 2, - QtCore.Qt.RightButton: 3, - # QtCore.Qt.XButton1: None, - # QtCore.Qt.XButton2: None, + buttond = {QtCore.Qt.LeftButton: MouseButton.LEFT, + QtCore.Qt.MidButton: MouseButton.MIDDLE, + QtCore.Qt.RightButton: MouseButton.RIGHT, + QtCore.Qt.XButton1: MouseButton.BACK, + QtCore.Qt.XButton2: MouseButton.FORWARD, } @_allow_super_init diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index 956a7d6adffc..994adf67da18 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -1425,8 +1425,10 @@ def _validate_linestyle(ls): # key-mappings (multi-character mappings should be a list/tuple) 'keymap.fullscreen': [['f', 'ctrl+f'], validate_stringlist], 'keymap.home': [['h', 'r', 'home'], validate_stringlist], - 'keymap.back': [['left', 'c', 'backspace'], validate_stringlist], - 'keymap.forward': [['right', 'v'], validate_stringlist], + 'keymap.back': [['left', 'c', 'backspace', 'MouseButton.BACK'], + validate_stringlist], + 'keymap.forward': [['right', 'v', 'MouseButton.FORWARD'], + validate_stringlist], 'keymap.pan': [['p'], validate_stringlist], 'keymap.zoom': [['o'], validate_stringlist], 'keymap.save': [['s', 'ctrl+s'], validate_stringlist], diff --git a/matplotlibrc.template b/matplotlibrc.template index 75512da2ecb2..df9ed2c7bcfc 100644 --- a/matplotlibrc.template +++ b/matplotlibrc.template @@ -583,8 +583,8 @@ ## Leave the field(s) empty if you don't need a key-map. (i.e., fullscreen : '') #keymap.fullscreen : f, ctrl+f ## toggling #keymap.home : h, r, home ## home or reset mnemonic -#keymap.back : left, c, backspace ## forward / backward keys to enable -#keymap.forward : right, v ## left handed quick navigation +#keymap.back : left, c, backspace, MouseButton.BACK ## forward / backward keys +#keymap.forward : right, v, MouseButton.FORWARD ## for quick navigation #keymap.pan : p ## pan mnemonic #keymap.zoom : o ## zoom mnemonic #keymap.save : s, ctrl+s ## saving current figure