Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 001368f

Browse files
authored
Merge pull request #10208 from DietmarSchwertberger/BACKENDWX_TOOLMANAGER_TOOLS
ENH: Add some wx specific tools for ToolManager
2 parents 206b5fe + f7e12cb commit 001368f

File tree

1 file changed

+167
-26
lines changed

1 file changed

+167
-26
lines changed

lib/matplotlib/backends/backend_wx.py

Lines changed: 167 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import six
2020
from six.moves import xrange
21+
import six
2122

2223
import sys
2324
import os
@@ -38,7 +39,7 @@
3839
from matplotlib.path import Path
3940
from matplotlib.transforms import Affine2D
4041
from matplotlib.widgets import SubplotTool
41-
from matplotlib import cbook, rcParams
42+
from matplotlib import cbook, rcParams, backend_tools
4243

4344
from . import wx_compat as wxc
4445
import wx
@@ -61,7 +62,7 @@ def DEBUG_MSG(string, lvl=3, o=None):
6162
# Jeremy, often times the commented line won't print but the
6263
# one below does. I think WX is redefining stderr, damned
6364
# beast
64-
#print >>sys.stderr, "%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls)
65+
# print >>sys.stderr, "%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls)
6566
print("%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls))
6667

6768

@@ -82,10 +83,6 @@ class fake_stderr(object):
8283
def write(self, msg):
8384
print("Stderr: %s\n\r" % msg)
8485

85-
#if _DEBUG < 5:
86-
#sys.excepthook = debug_on_error
87-
#WxLogger =wx.LogStderr()
88-
#sys.stderr = fake_stderr
8986

9087
# the True dots per inch on the screen; should be display dependent
9188
# see
@@ -410,7 +407,7 @@ class GraphicsContextWx(GraphicsContextBase):
410407

411408
def __init__(self, bitmap, renderer):
412409
GraphicsContextBase.__init__(self)
413-
#assert self.Ok(), "wxMemoryDC not OK to use"
410+
# assert self.Ok(), "wxMemoryDC not OK to use"
414411
DEBUG_MSG("__init__()", 1, self)
415412
DEBUG_MSG("__init__() 2: %s" % bitmap, 1, self)
416413

@@ -1214,10 +1211,10 @@ def __init__(self, num, fig):
12141211
# This is not currently working on Linux and is untested elsewhere.
12151212
# icon_path = os.path.join(matplotlib.rcParams['datapath'],
12161213
# 'images', 'matplotlib.png')
1217-
#icon = wx.IconFromBitmap(wx.Bitmap(icon_path))
1218-
# for xpm type icons try:
1219-
#icon = wx.Icon(icon_path, wx.BITMAP_TYPE_XPM)
1220-
# self.SetIcon(icon)
1214+
# icon = wx.IconFromBitmap(wx.Bitmap(icon_path))
1215+
# for xpm type icons try:
1216+
# icon = wx.Icon(icon_path, wx.BITMAP_TYPE_XPM)
1217+
# self.SetIcon(icon)
12211218

12221219
self.figmgr = FigureManagerWx(self.canvas, num, self)
12231220

@@ -1321,7 +1318,8 @@ def resize(self, width, height):
13211318
# Identifiers for toolbar controls - images_wx contains bitmaps for the images
13221319
# used in the controls. wxWindows does not provide any stock images, so I've
13231320
# 'stolen' those from GTK2, and transformed them into the appropriate format.
1324-
#import images_wx
1321+
# import images_wx
1322+
13251323

13261324
_NTB_AXISMENU = wx.NewId()
13271325
_NTB_AXISMENU_BUTTON = wx.NewId()
@@ -1333,7 +1331,7 @@ def resize(self, width, height):
13331331
_NTB_Y_PAN_DOWN = wx.NewId()
13341332
_NTB_Y_ZOOMIN = wx.NewId()
13351333
_NTB_Y_ZOOMOUT = wx.NewId()
1336-
#_NTB_SUBPLOT =wx.NewId()
1334+
# _NTB_SUBPLOT =wx.NewId()
13371335
_NTB_SAVE = wx.NewId()
13381336
_NTB_CLOSE = wx.NewId()
13391337

@@ -1523,8 +1521,8 @@ def _init_toolbar(self):
15231521
continue
15241522
self.wx_ids[text] = wx.NewId()
15251523
wxc._AddTool(self, self.wx_ids, text,
1526-
_load_bitmap(image_file + '.png'),
1527-
tooltip_text)
1524+
_load_bitmap(image_file + '.png'),
1525+
tooltip_text)
15281526

15291527
self.Bind(wx.EVT_TOOL, getattr(self, callback),
15301528
id=self.wx_ids[text])
@@ -1594,12 +1592,6 @@ def set_cursor(self, cursor):
15941592
self.canvas.SetCursor(cursor)
15951593
self.canvas.Update()
15961594

1597-
def release(self, event):
1598-
try:
1599-
del self.lastrect
1600-
except AttributeError:
1601-
pass
1602-
16031595
@cbook.deprecated("2.1", alternative="canvas.draw_idle")
16041596
def dynamic_update(self):
16051597
d = self._idle
@@ -1717,7 +1709,7 @@ def __init__(self, parent):
17171709
wx.StatusBar.__init__(self, parent, -1)
17181710
self.SetFieldsCount(2)
17191711
self.SetStatusText("None", 1)
1720-
#self.SetStatusText("Measurement: None", 2)
1712+
# self.SetStatusText("Measurement: None", 2)
17211713
# self.Reposition()
17221714

17231715
def set_function(self, string):
@@ -1727,7 +1719,155 @@ def set_function(self, string):
17271719
# self.SetStatusText("Measurement: %s" % string, 2)
17281720

17291721

1730-
#< Additions for printing support: Matt Newville
1722+
# tools for matplotlib.backend_managers.ToolManager:
1723+
# for now only SaveFigure, SetCursor and Rubberband are implemented
1724+
# once a ToolbarWx is implemented, also FigureManagerWx needs to be
1725+
# modified, similar to pull request #9934
1726+
1727+
class SaveFigureWx(backend_tools.SaveFigureBase):
1728+
def trigger(self, *args):
1729+
# Fetch the required filename and file type.
1730+
filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards()
1731+
default_dir = os.path.expanduser(
1732+
matplotlib.rcParams['savefig.directory'])
1733+
default_file = self.canvas.get_default_filename()
1734+
dlg = wx.FileDialog(self.canvas.GetTopLevelParent(), "Save to file",
1735+
default_dir, default_file, filetypes,
1736+
wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
1737+
dlg.SetFilterIndex(filter_index)
1738+
if dlg.ShowModal() != wx.ID_OK:
1739+
return
1740+
1741+
dirname = dlg.GetDirectory()
1742+
filename = dlg.GetFilename()
1743+
DEBUG_MSG('Save file dir:%s name:%s' % (dirname, filename), 3, self)
1744+
format = exts[dlg.GetFilterIndex()]
1745+
basename, ext = os.path.splitext(filename)
1746+
if ext.startswith('.'):
1747+
ext = ext[1:]
1748+
if ext in ('svg', 'pdf', 'ps', 'eps', 'png') and format != ext:
1749+
# looks like they forgot to set the image type drop
1750+
# down, going with the extension.
1751+
warnings.warn(
1752+
'extension %s did not match the selected '
1753+
'image type %s; going with %s' %
1754+
(ext, format, ext), stacklevel=0)
1755+
format = ext
1756+
if default_dir != "":
1757+
matplotlib.rcParams['savefig.directory'] = dirname
1758+
try:
1759+
self.canvas.figure.savefig(
1760+
os.path.join(dirname, filename), format=format)
1761+
except Exception as e:
1762+
error_msg_wx(str(e))
1763+
1764+
1765+
class SetCursorWx(backend_tools.SetCursorBase):
1766+
def set_cursor(self, cursor):
1767+
cursor = wxc.Cursor(cursord[cursor])
1768+
self.canvas.SetCursor(cursor)
1769+
self.canvas.Update()
1770+
1771+
1772+
if 'wxMac' not in wx.PlatformInfo:
1773+
# on most platforms, use overlay
1774+
class RubberbandWx(backend_tools.RubberbandBase):
1775+
def __init__(self, *args, **kwargs):
1776+
backend_tools.RubberbandBase.__init__(self, *args, **kwargs)
1777+
self.wxoverlay = None
1778+
1779+
def draw_rubberband(self, x0, y0, x1, y1):
1780+
# Use an Overlay to draw a rubberband-like bounding box.
1781+
if self.wxoverlay is None:
1782+
self.wxoverlay = wx.Overlay()
1783+
dc = wx.ClientDC(self.canvas)
1784+
odc = wx.DCOverlay(self.wxoverlay, dc)
1785+
odc.Clear()
1786+
1787+
dc = wx.GCDC(dc)
1788+
1789+
height = self.canvas.figure.bbox.height
1790+
y1 = height - y1
1791+
y0 = height - y0
1792+
1793+
if y1 < y0:
1794+
y0, y1 = y1, y0
1795+
if x1 < y0:
1796+
x0, x1 = x1, x0
1797+
1798+
w = x1 - x0
1799+
h = y1 - y0
1800+
rect = wx.Rect(x0, y0, w, h)
1801+
1802+
rubberBandColor = '#C0C0FF' # or load from config?
1803+
1804+
# Set a pen for the border
1805+
color = wxc.NamedColour(rubberBandColor)
1806+
dc.SetPen(wx.Pen(color, 1))
1807+
1808+
# use the same color, plus alpha for the brush
1809+
r, g, b, a = color.Get(True)
1810+
color.Set(r, g, b, 0x60)
1811+
dc.SetBrush(wx.Brush(color))
1812+
if wxc.is_phoenix:
1813+
dc.DrawRectangle(rect)
1814+
else:
1815+
dc.DrawRectangleRect(rect)
1816+
1817+
def remove_rubberband(self):
1818+
if self.wxoverlay is None:
1819+
return
1820+
self.wxoverlay.Reset()
1821+
self.wxoverlay = None
1822+
1823+
else:
1824+
# on Mac OS retina displays DCOverlay does not work
1825+
# and dc.SetLogicalFunction does not have an effect on any display
1826+
# the workaround is to blit the full image for remove_rubberband
1827+
class RubberbandWx(backend_tools.RubberbandBase):
1828+
def __init__(self, *args, **kwargs):
1829+
backend_tools.RubberbandBase.__init__(self, *args, **kwargs)
1830+
self._rect = None
1831+
1832+
def draw_rubberband(self, x0, y0, x1, y1):
1833+
dc = wx.ClientDC(self.canvas)
1834+
# this would be required if the Canvas is a ScrolledWindow,
1835+
# which is not the case for now
1836+
# self.PrepareDC(dc)
1837+
1838+
# delete old rubberband
1839+
if self._rect:
1840+
self.remove_rubberband(dc)
1841+
1842+
# draw new rubberband
1843+
dc.SetPen(wx.Pen(wx.BLACK, 1, wx.SOLID))
1844+
dc.SetBrush(wx.TRANSPARENT_BRUSH)
1845+
self._rect = (x0, self.canvas._height-y0, x1-x0, -y1+y0)
1846+
if wxc.is_phoenix:
1847+
dc.DrawRectangle(self._rect)
1848+
else:
1849+
dc.DrawRectangleRect(self._rect)
1850+
1851+
def remove_rubberband(self, dc=None):
1852+
if not self._rect:
1853+
return
1854+
if self.canvas.bitmap:
1855+
if dc is None:
1856+
dc = wx.ClientDC(self.canvas)
1857+
dc.DrawBitmap(self.canvas.bitmap, 0, 0)
1858+
# for testing the method on Windows, use this code instead:
1859+
# img = self.canvas.bitmap.ConvertToImage()
1860+
# bmp = img.ConvertToBitmap()
1861+
# dc.DrawBitmap(bmp, 0, 0)
1862+
self._rect = None
1863+
1864+
1865+
backend_tools.ToolSaveFigure = SaveFigureWx
1866+
backend_tools.ToolSetCursor = SetCursorWx
1867+
backend_tools.ToolRubberband = RubberbandWx
1868+
1869+
1870+
# < Additions for printing support: Matt Newville
17311871

17321872
class PrintoutWx(wx.Printout):
17331873
"""
@@ -1802,25 +1942,26 @@ def OnPrintPage(self, page):
18021942
# this cute little number avoid API inconsistencies in wx
18031943
try:
18041944
dc.DrawBitmap(self.canvas.bitmap, 0, 0)
1805-
except:
1945+
except Exception:
18061946
try:
18071947
dc.DrawBitmap(self.canvas.bitmap, (0, 0))
1808-
except:
1948+
except Exception:
18091949
pass
18101950

18111951
# restore original figure resolution
18121952
self.canvas.figure.set_facecolor(bgcolor)
18131953
self.canvas.figure.dpi = fig_dpi
18141954
self.canvas.draw()
18151955
return True
1816-
#>
1956+
# >
18171957

18181958
########################################################################
18191959
#
18201960
# Now just provide the standard names that backend.__init__ is expecting
18211961
#
18221962
########################################################################
18231963

1964+
18241965
Toolbar = NavigationToolbar2Wx
18251966

18261967

0 commit comments

Comments
 (0)