8000 Several fixes to WX. Modifier keys implemented for qt, wx and gtk bac… · matplotlib/matplotlib@df0a112 · GitHub
[go: up one dir, main page]

Skip to content

Commit df0a112

Browse files
pelsonpelson
authored andcommitted
Several fixes to WX. Modifier keys implemented for qt, wx and gtk backends.
1 parent 3bbbd0a commit df0a112

File tree

4 files changed

+66
-62
lines changed

4 files changed

+66
-62
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,8 +2767,6 @@ def drag_zoom(self, event):
27672767

27682768
self.draw_rubberband(event, x, y, lastx, lasty)
27692769

2770-
2771-
27722770
def release_zoom(self, event):
27732771
'the release mouse button callback in zoom to rect mode'
27742772
for zoom_id in self._ids_zoom:
@@ -2894,8 +2892,6 @@ def draw(self):
28942892
loc.refresh()
28952893
self.canvas.draw()
28962894

2897-
2898-
28992895
def _update_view(self):
29002896
'''update the viewlim and position from the view and
29012897
position stack for each axes

lib/matplotlib/backends/backend_gtk.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,14 +322,17 @@ def enter_notify_event(self, widget, event):
322322
def _get_key(self, event):
323323
if event.keyval in self.keyvald:
324324
key = self.keyvald[event.keyval]
325-
elif event.keyval <256:
325+
elif event.keyval < 256:
326326
key = chr(event.keyval)
327327
else:
328328
key = None
329329

330-
ctrl = event.state & gdk.CONTROL_MASK
331-
shift = event.state & gdk.SHIFT_MASK
332-
return key
330+
for key_mask, prefix in ([gdk.CONTROL_MASK, 'ctrl'],
331+
[gdk.MOD1_MASK, 'alt'], ):
332+
if event.state & key_mask:
333+
key = '{}+{}'.format(prefix, key)
334+
335+
return key
333336

334337

335338
def configure_event(self, widget, event):

lib/matplotlib/backends/backend_qt4.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import division, print_function
22
import math
33
import os
4+
import signal
45
import sys
56

67
import matplotlib
@@ -60,8 +61,10 @@ def _create_qApp():
6061

6162
class Show(ShowBase):
6263
def mainloop(self):
63-
QtGui.qApp.exec_()
64+
# allow KeyboardInterrupt exceptions to close the plot window.
65+
signal.signal(signal.SIGINT, signal.SIG_DFL)
6466

67+
QtGui.qApp.exec_()
6568
show = Show()
6669

6770

@@ -268,13 +271,36 @@ def minumumSizeHint( self ):
268271
def _get_key( self, event ):
269272
if event.isAutoRepeat():
270273
return None
274+
271275
if event.key() < 256:
272-
key = str(event.text())
276+
key = unicode(event.text())
277+
278+
# if the control key is being pressed, we don't get the correct
279+
# characters, so interpret them directly from the event.key().
280+
# Unfortunately, this means that we cannot handle key's case
281+
# since event.key() is not case sensitve, whereas event.text() is,
282+
# Finally, since it is not possible to get the CapsLock state
283+
# we cannot accurately compute the case of a pressed key when
284+
# ctrl+shift+p is pressed.
285+
if int(event.modifiers()) & QtCore.Qt.ControlModifier and event.key() < 256:
286+
# we always get an uppercase charater
287+
key = chr(event.key())
288+
# if shift is not being pressed, lowercase it (as mentioned,
289+
# this does not take into account the CapsLock state)
290+
if not int(event.modifiers()) & QtCore.Qt.ShiftModifier:
291+
key = key.lower()
292+
273293
elif event.key() in self.keyvald:
274-
key = self.keyvald[ event.key() ]
294+
key = self.keyvald[event.key()]
275295
else:
276296
key = None
277297

298+
if key is not None:
299+
for modifier, Qt_key, prefix in [(QtCore.Qt.ControlModifier, QtCore.Qt.Key_Control, 'ctrl'),
300+
(QtCore.Qt.AltModifier, QtCore.Qt.Key_Alt, 'alt')]:
301+
if event.key() != Qt_key and int(event.modifiers()) & modifier == modifier:
302+
key = '{}+{}'.format(prefix, key)
303+
278304
return key
279305

280306
def new_timer(self, *args, **kwargs):

lib/matplotlib/backends/backend_wx.py

Lines changed: 30 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,13 +1242,18 @@ def _get_key(self, evt):
12421242
keyval = evt.m_keyCode
12431243
if keyval in self.keyvald:
12441244
key = self.keyvald[keyval]
1245-
elif keyval <256:
1245+
elif keyval < 256:
12461246
key = chr(keyval)
1247+
# wx always returns an uppercase, so make it lowercase if the shift
1248+
# key is not depressed (NOTE: this will not handle Caps Lock)
1249+
if not evt.ShiftDown():
1250+
key = key.lower()
12471251
else:
12481252
key = None
12491253

1250-
# why is wx upcasing this?
1251-
if key is not None: key = key.lower()
1254+
for meth, prefix in ([evt.ControlDown, 'ctrl'], [evt.AltDown, 'alt'], ):
1255+
if meth():
1256+
key = '{}+{}'.format(prefix, key)
12521257

12531258
return key
12541259

@@ -1476,6 +1481,7 @@ def __init__(self, num, fig):
14761481
self.SetStatusBar(statbar)
14771482
self.canvas = self.get_canvas(fig)
14781483
self.canvas.SetInitialSize(wx.Size(fig.bbox.width, fig.bbox.height))
1484+
self.canvas.SetFocus()
14791485
self.sizer =wx.BoxSizer(wx.VERTICAL)
14801486
self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND)
14811487
# By adding toolbar in sizer, we are able to put it at the bottom
@@ -1742,8 +1748,6 @@ def updateButtonText(self, lst):
17421748
self.SetLabel("Axes: %s" % axis_txt[:-1])
17431749

17441750

1745-
1746-
17471751
cursord = {
17481752
cursors.MOVE : wx.CURSOR_HAND,
17491753
cursors.HAND : wx.CURSOR_HAND,
@@ -1787,57 +1791,33 @@ def _init_toolbar(self):
17871791
DEBUG_MSG("_init_toolbar", 1, self)
17881792

17891793
self._parent = self.canvas.GetParent()
1790-
_NTB2_HOME =wx.NewId()
1791-
self._NTB2_BACK =wx.NewId()
1792-
self._NTB2_FORWARD =wx.NewId()
1793-
self._NTB2_PAN =wx.NewId()
1794-
self._NTB2_ZOOM =wx.NewId()
1795-
_NTB2_SAVE = wx.NewId()
1796-
_NTB2_SUBPLOT =wx.NewId()
1797-
1798-
self.SetToolBitmapSize(wx.Size(24,24))
1799-
1800-
self.AddSimpleTool(_NTB2_HOME, _load_bitmap('home.png'),
1801-
'Home', 'Reset original view')
1802-
self.AddSimpleTool(self._NTB2_BACK, _load_bitmap('back.png'),
1803-
'Back', 'Back navigation view')
1804-
self.AddSimpleTool(self._NTB2_FORWARD, _load_bitmap('forward.png'),
1805-
'Forward', 'Forward navigation view')
1806-
# todo: get new bitmap
1807-
self.AddCheckTool(self._NTB2_PAN, _load_bitmap('move.png'),
1808-
shortHelp='Pan',
1809-
longHelp='Pan with left, zoom with right')
1810-
self.AddCheckTool(self._NTB2_ZOOM, _load_bitmap('zoom_to_rect.png'),
1811-
shortHelp='Zoom', longHelp='Zoom to rectangle')
18121794

1813-
self.AddSeparator()
1814-
self.AddSimpleTool(_NTB2_SUBPLOT, _load_bitmap('subplots.png'),
1815-
'Configure subplots', 'Configure subplot parameters')
18161795

1817-
self.AddSimpleTool(_NTB2_SAVE, _load_bitmap('filesave.png'),
1818-
'Save', 'Save plot contents to file')
1819-
1820-
bind(self, wx.EVT_TOOL, self.home, id=_NTB2_HOME)
1821-
bind(self, wx.EVT_TOOL, self.forward, id=self._NTB2_FORWARD)
1822-
bind(self, wx.EVT_TOOL, self.back, id=self._NTB2_BACK)
1823-
bind(self, wx.EVT_TOOL, self.zoom, id=self._NTB2_ZOOM)
1824-
bind(self, wx.EVT_TOOL, self.pan, id=self._NTB2_PAN)
1825-
bind(self, wx.EVT_TOOL, self.configure_subplot, id=_NTB2_SUBPLOT)
1826-
bind(self, wx.EVT_TOOL, self.save, id=_NTB2_SAVE)
1796+
self.wx_ids = {}
1797+
for text, tooltip_text, image_file, callback in self.toolitems:
1798+
if text is None:
1799+
self.AddSeparator()
1800+
continue
1801+
self.wx_ids[text] = wx.NewId()
1802+
if text in ['Pan', 'Zoom']:
1803+
self.AddCheckTool(self.wx_ids[text], _load_bitmap(image_file + '.png'),
1804+
shortHelp=text, longHelp=tooltip_text)
1805+
else:
1806+
self.AddSimpleTool(self.wx_ids[text], _load_bitmap(image_file + '.png'),
1807+
text, tooltip_text)
1808+
bind(self, wx.EVT_TOOL, getattr(self, callback), id=self.wx_ids[text])
18271809

18281810
self.Realize()
18291811

1830-
18311812
def zoom(self, *args):
1832-
self.ToggleTool(self._NTB2_PAN, False)
1813+
self.ToggleTool(self.wx_ids['Pan'], False)
18331814
NavigationToolbar2.zoom(self, *args)
18341815

18351816
def pan(self, *args):
1836-
self.ToggleTool(self._NTB2_ZOOM, False)
1817+
self.ToggleTool(self.wx_ids['Zoom'], False)
18371818
NavigationToolbar2.pan(self, *args)
18381819

1839-
1840-
def configure_subplot(self, evt):
1820+
def configure_subplots(self, evt):
18411821
frame = wx.Frame(None, -1, "Configure subplots")
18421822

18431823
toolfig = Figure((6,3))
@@ -1855,7 +1835,7 @@ def configure_subplot(self, evt):
18551835
tool = SubplotTool(self.canvas.figure, toolfig)
18561836
frame.Show()
18571837

1858-
def save(self, evt):
1838+
def save_figure(self, *args):
18591839
# Fetch the required filename and file type.
18601840
filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards()
18611841
default_file = "image." + self.canvas.get_default_filetype()
@@ -1881,7 +1861,7 @@ def save(self, evt):
18811861
os.path.join(dirname, filename), format=format)
18821862
except Exception as e:
18831863
error_msg_wx(str(e))
1884-
1864+
18851865
def set_cursor(self, cursor):
18861866
cursor =wx.StockCursor(cursord[cursor])
18871867
self.canvas.SetCursor( cursor )
@@ -1948,8 +1928,8 @@ def set_message(self, s):
19481928
def set_history_buttons(self):
19491929
can_backward = (self._views._pos > 0)
19501930
can_forward = (self._views._pos < len(self._views._elements) - 1)
1951-
self.EnableTool(self._NTB2_BACK, can_backward)
1952-
self.EnableTool(self._NTB2_FORWARD, can_forward)
1931+
self.EnableTool(self.wx_ids['Back'], can_backward)
1932+
self.EnableTool(self.wx_ids['Forward'], can_forward)
19531933

19541934

19551935
class NavigationToolbarWx(wx.ToolBar):
@@ -2149,13 +2129,12 @@ def _onMouseWheel(self, evt):
21492129
direction = -1
21502130
self.button_fn(direction)
21512131

2152-
_onSave = NavigationToolbar2Wx.save
2132+
_onSave = NavigationToolbar2Wx.save_figure
21532133

21542134
def _onClose(self, evt):
21552135
self.GetParent().Destroy()
21562136

21572137

2158-
21592138
class StatusBarWx(wx.StatusBar):
21602139
"""
21612140
A status bar is added to _FigureFrame to allow measurements and the

0 commit comments

Comments
 (0)
0