|
1 | 1 | """
|
2 |
| - A wxPython backend for matplotlib, based (very heavily) on |
3 |
| - backend_template.py and backend_gtk.py |
| 2 | +A wxPython backend for matplotlib. |
4 | 3 |
|
5 |
| - Author: Jeremy O'Donoghue ([email protected]) |
6 |
| -
|
7 |
| - Derived from original copyright work by John Hunter |
8 |
| - |
9 |
| -
|
10 |
| - Copyright (C) Jeremy O'Donoghue & John Hunter, 2003-4 |
11 |
| -
|
12 |
| - License: This work is licensed under a PSF compatible license. A copy |
13 |
| - should be included with this source code. |
| 4 | +Originally contributed by Jeremy O'Donoghue ([email protected]) and John |
| 5 | + |
14 | 6 |
|
| 7 | +Copyright (C) Jeremy O'Donoghue & John Hunter, 2003-4. |
15 | 8 | """
|
16 |
| -from __future__ import (absolute_import, division, print_function, |
17 |
| - unicode_literals) |
18 | 9 |
|
19 | 10 | import six
|
20 | 11 |
|
21 |
| -import sys |
22 |
| -import os |
23 | 12 | import os.path
|
24 | 13 | import math
|
25 |
| -import weakref |
| 14 | +import sys |
26 | 15 | import warnings
|
| 16 | +import weakref |
27 | 17 |
|
28 | 18 | import matplotlib
|
29 | 19 | from matplotlib.backend_bases import (
|
|
39 | 29 | from matplotlib.widgets import SubplotTool
|
40 | 30 | from matplotlib import cbook, rcParams, backend_tools
|
41 | 31 |
|
42 |
| -from . import wx_compat as wxc |
43 | 32 | import wx
|
44 | 33 |
|
45 | 34 | # Debugging settings here...
|
@@ -173,14 +162,45 @@ class RendererWx(RendererBase):
|
173 | 162 | # describes the colour and weight of any lines drawn, and a wxBrush
|
174 | 163 | # which describes the fill colour of any closed polygon.
|
175 | 164 |
|
176 |
| - fontweights = wxc.fontweights |
177 |
| - fontangles = wxc.fontangles |
| 165 | + # Font styles, families and weight. |
| 166 | + fontweights = { |
| 167 | + 100: wx.FONTWEIGHT_LIGHT, |
| 168 | + 200: wx.FONTWEIGHT_LIGHT, |
| 169 | + 300: wx.FONTWEIGHT_LIGHT, |
| 170 | + 400: wx.FONTWEIGHT_NORMAL, |
| 171 | + 500: wx.FONTWEIGHT_NORMAL, |
| 172 | + 600: wx.FONTWEIGHT_NORMAL, |
| 173 | + 700: wx.FONTWEIGHT_BOLD, |
| 174 | + 800: wx.FONTWEIGHT_BOLD, |
| 175 | + 900: wx.FONTWEIGHT_BOLD, |
| 176 | + 'ultralight': wx.FONTWEIGHT_LIGHT, |
| 177 | + 'light': wx.FONTWEIGHT_LIGHT, |
| 178 | + 'normal': wx.FONTWEIGHT_NORMAL, |
| 179 | + 'medium': wx.FONTWEIGHT_NORMAL, |
| 180 | + 'semibold': wx.FONTWEIGHT_NORMAL, |
| 181 | + 'bold': wx.FONTWEIGHT_BOLD, |
| 182 | + 'heavy': wx.FONTWEIGHT_BOLD, |
| 183 | + 'ultrabold': wx.FONTWEIGHT_BOLD, |
| 184 | + 'black': wx.FONTWEIGHT_BOLD, |
| 185 | + } |
| 186 | + fontangles = { |
| 187 | + 'italic': wx.FONTSTYLE_ITALIC, |
| 188 | + 'normal': wx.FONTSTYLE_NORMAL, |
| 189 | + 'oblique': wx.FONTSTYLE_SLANT, |
| 190 | + } |
178 | 191 |
|
179 |
| - # wxPython allows for portable font styles, choosing them appropriately |
180 |
| - # for the target platform. Map some standard font names to the portable |
181 |
| - # styles |
| 192 | + # wxPython allows for portable font styles, choosing them appropriately for |
| 193 | + # the target platform. Map some standard font names to the portable styles. |
182 | 194 | # QUESTION: Is it be wise to agree standard fontnames across all backends?
|
183 |
| - fontnames = wxc.fontnames |
| 195 | + fontnames = { |
| 196 | + 'Sans': wx.FONTFAMILY_SWISS, |
| 197 | + 'Roman': wx.FONTFAMILY_ROMAN, |
| 198 | + 'Script': wx.FONTFAMILY_SCRIPT, |
| 199 | + 'Decorative': wx.FONTFAMILY_DECORATIVE, |
| 200 | + 'Modern': wx.FONTFAMILY_MODERN, |
| 201 | + 'Courier': wx.FONTFAMILY_MODERN, |
| 202 | + 'courier': wx.FONTFAMILY_MODERN, |
| 203 | + } |
184 | 204 |
|
185 | 205 | def __init__(self, bitmap, dpi):
|
186 | 206 | """
|
@@ -285,7 +305,7 @@ def draw_image(self, gc, x, y, im):
|
285 | 305 | w = self.width
|
286 | 306 | h = self.height
|
287 | 307 | rows, cols = im.shape[:2]
|
288 |
| - bitmap = wxc.BitmapFromBuffer(cols, rows, im.tostring()) |
| 308 | + bitmap = wx.Bitmap.FromBufferRGBA(cols, rows, im.tostring()) |
289 | 309 | gc = self.get_gc()
|
290 | 310 | gc.select()
|
291 | 311 | gc.gfx_ctx.DrawBitmap(bitmap, int(l), int(self.height - b),
|
@@ -611,27 +631,8 @@ def __init__(self, parent, id, figure):
|
611 | 631 |
|
612 | 632 | wx.Panel.__init__(self, parent, id, size=wx.Size(w, h))
|
613 | 633 |
|
614 |
| - def do_nothing(*args, **kwargs): |
615 |
| - warnings.warn( |
616 |
| - "could not find a setinitialsize function for backend_wx; " |
617 |
| - "please report your wxpython version=%s " |
618 |
| - "to the matplotlib developers list" % |
619 |
| - wxc.backend_version) |
620 |
| - pass |
621 |
| - |
622 |
| - # try to find the set size func across wx versions |
623 |
| - try: |
624 |
| - getattr(self, 'SetInitialSize') |
625 |
| - except AttributeError: |
626 |
| - self.SetInitialSize = getattr(self, 'SetBestFittingSize', |
627 |
| - do_nothing) |
628 |
| - |
629 |
| - if not hasattr(self, 'IsShownOnScreen'): |
630 |
| - self.IsShownOnScreen = getattr(self, 'IsVisible', |
631 |
| - lambda *args: True) |
632 |
| - |
633 | 634 | # Create the drawing bitmap
|
634 |
| - self.bitmap = wxc.EmptyBitmap(w, h) |
| 635 | + self.bitmap = wx.Bitmap(w, h) |
635 | 636 | DEBUG_MSG("__init__() - bitmap w:%d h:%d" % (w, h), 2, self)
|
636 | 637 | # TODO: Add support for 'point' inspection and plot navigation.
|
637 | 638 | self._isDrawn = False
|
@@ -733,7 +734,7 @@ def start_event_loop(self, timeout=0):
|
733 | 734 | self.Bind(wx.EVT_TIMER, self.stop_event_loop, id=id)
|
734 | 735 |
|
735 | 736 | # Event loop handler for start/stop event loop
|
736 |
| - self._event_loop = wxc.EventLoop() |
| 737 | + self._event_loop = wx.GUIEventLoop() |
737 | 738 | self._event_loop.Run()
|
738 | 739 | timer.Stop()
|
739 | 740 |
|
@@ -845,7 +846,7 @@ def _onSize(self, evt):
|
845 | 846 | return
|
846 | 847 | self._width, self._height = size
|
847 | 848 | # Create a new, correctly sized bitmap
|
848 |
| - self.bitmap = wxc.EmptyBitmap(self._width, self._height) |
| 849 | + self.bitmap = wx.Bitmap(self._width, self._height) |
849 | 850 |
|
850 | 851 | self._isDrawn = False
|
851 | 852 |
|
@@ -1083,7 +1084,7 @@ def _print_image(self, filename, filetype, *args, **kwargs):
|
1083 | 1084 | width = int(math.ceil(width))
|
1084 | 1085 | height = int(math.ceil(height))
|
1085 | 1086 |
|
1086 |
| - self.bitmap = wxc.EmptyBitmap(width, height) |
| 1087 | + self.bitmap = wx.Bitmap(width, height) |
1087 | 1088 |
|
1088 | 1089 | renderer = RendererWx(self.bitmap, self.figure.dpi)
|
1089 | 1090 |
|
@@ -1172,12 +1173,8 @@ def __init__(self, num, fig):
|
1172 | 1173 | self.toolbar.Realize()
|
1173 | 1174 | # On Windows platform, default window size is incorrect, so set
|
1174 | 1175 | # toolbar width to figure width.
|
1175 |
| - if wxc.is_phoenix: |
1176 |
| - tw, th = self.toolbar.GetSize() |
1177 |
| - fw, fh = self.canvas.GetSize() |
1178 |
| - else: |
1179 |
| - tw, th = self.toolbar.GetSizeTuple() |
1180 |
| - fw, fh = self.canvas.GetSizeTuple() |
| 1176 | + tw, th = self.toolbar.GetSize() |
| 1177 | + fw, fh = self.canvas.GetSize() |
1181 | 1178 | # By adding toolbar in sizer, we are able to put it at the bottom
|
1182 | 1179 | # of the frame - so appearance is closer to GTK version.
|
1183 | 1180 | self.toolbar.SetSize(wx.Size(fw, th))
|
@@ -1368,12 +1365,8 @@ def Destroy(self):
|
1368 | 1365 |
|
1369 | 1366 | def _onMenuButton(self, evt):
|
1370 | 1367 | """Handle menu button pressed."""
|
1371 |
| - if wxc.is_phoenix: |
1372 |
| - x, y = self.GetPosition() |
1373 |
| - w, h = self.GetSize() |
1374 |
| - else: |
1375 |
| - x, y = self.GetPositionTuple() |
1376 |
| - w, h = self.GetSizeTuple() |
| 1368 | + x, y = self.GetPosition() |
| 1369 | + w, h = self.GetSize() |
1377 | 1370 | self.PopupMenuXY(self._menu, x, y + h - 4)
|
1378 | 1371 | # When menu returned, indicate selection in button
|
1379 | 1372 | evt.Skip()
|
@@ -1500,11 +1493,15 @@ def _init_toolbar(self):
|
1500 | 1493 | if text is None:
|
1501 | 1494 | self.AddSeparator()
|
1502 | 1495 | continue
|
1503 |
| - self.wx_ids[text] = wx.NewId() |
1504 |
| - wxc._AddTool(self, self.wx_ids, text, |
1505 |
| - _load_bitmap(image_file + '.png'), |
1506 |
| - tooltip_text) |
1507 |
| - |
| 1496 | + self.wx_ids[text] = ( |
| 1497 | + self.AddTool( |
| 1498 | + -1, |
| 1499 | + bitmap=_load_bitmap(image_file + ".png"), |
| 1500 | + bmpDisabled=wx.NullBitmap, |
| 1501 | + label=text, shortHelp=text, longHelp=tooltip_text, |
| 1502 | + kind=(wx.ITEM_CHECK if text in ["Pan", "Zoom"] |
| 1503 | + else wx.ITEM_NORMAL)) |
| 1504 | + .Id) |
1508 | 1505 | self.Bind(wx.EVT_TOOL, getattr(self, callback),
|
1509 | 1506 | id=self.wx_ids[text])
|
1510 | 1507 |
|
@@ -1569,7 +1566,7 @@ def save_figure(self, *args):
|
1569 | 1566 | error_msg_wx(str(e))
|
1570 | 1567 |
|
1571 | 1568 | def set_cursor(self, cursor):
|
1572 |
| - cursor = wxc.Cursor(cursord[cursor]) |
| 1569 | + cursor = wx.Cursor(cursord[cursor]) |
1573 | 1570 | self.canvas.SetCursor(cursor)
|
1574 | 1571 | self.canvas.Update()
|
1575 | 1572 |
|
@@ -1645,17 +1642,14 @@ def draw_rubberband(self, event, x0, y0, x1, y1):
|
1645 | 1642 | rubberBandColor = '#C0C0FF' # or load from config?
|
1646 | 1643 |
|
1647 | 1644 | # Set a pen for the border
|
1648 |
| - color = wxc.NamedColour(rubberBandColor) |
| 1645 | + color = wx.Colour(rubberBandColor) |
1649 | 1646 | dc.SetPen(wx.Pen(color, 1))
|
1650 | 1647 |
|
1651 | 1648 | # use the same color, plus alpha for the brush
|
1652 | 1649 | r, g, b, a = color.Get(True)
|
1653 | 1650 | color.Set(r, g, b, 0x60)
|
1654 | 1651 | dc.SetBrush(wx.Brush(color))
|
1655 |
| - if wxc.is_phoenix: |
1656 |
| - dc.DrawRectangle(rect) |
1657 |
| - else: |
1658 |
| - dc.DrawRectangleRect(rect) |
| 1652 | + dc.DrawRectangle(rect) |
1659 | 1653 |
|
1660 | 1654 | def set_status_bar(self, statbar):
|
1661 | 1655 | self.statbar = statbar
|
@@ -1742,7 +1736,7 @@ def trigger(self, *args):
|
1742 | 1736 |
|
1743 | 1737 | class SetCursorWx(backend_tools.SetCursorBase):
|
1744 | 1738 | def set_cursor(self, cursor):
|
1745 |
| - cursor = wxc.Cursor(cursord[cursor]) |
| 1739 | + cursor = wx.Cursor(cursord[cursor]) |
1746 | 1740 | self.canvas.SetCursor(cursor)
|
1747 | 1741 | self.canvas.Update()
|
1748 | 1742 |
|
@@ -1780,17 +1774,14 @@ def draw_rubberband(self, x0, y0, x1, y1):
|
1780 | 1774 | rubberBandColor = '#C0C0FF' # or load from config?
|
1781 | 1775 |
|
1782 | 1776 | # Set a pen for the border
|
1783 |
| - color = wxc.NamedColour(rubberBandColor) |
| 1777 | + color = wx.Colour(rubberBandColor) |
1784 | 1778 | dc.SetPen(wx.Pen(color, 1))
|
1785 | 1779 |
|
1786 | 1780 | # use the same color, plus alpha for the brush
|
1787 | 1781 | r, g, b, a = color.Get(True)
|
1788 | 1782 | color.Set(r, g, b, 0x60)
|
1789 | 1783 | dc.SetBrush(wx.Brush(color))
|
1790 |
| - if wxc.is_phoenix: |
1791 |
| - dc.DrawRectangle(rect) |
1792 |
| - else: |
1793 |
| - dc.DrawRectangleRect(rect) |
| 1784 | + dc.DrawRectangle(rect) |
1794 | 1785 |
|
1795 | 1786 | def remove_rubberband(self):
|
1796 | 1787 | if self.wxoverlay is None:
|
@@ -1821,10 +1812,7 @@ def draw_rubberband(self, x0, y0, x1, y1):
|
1821 | 1812 | dc.SetPen(wx.Pen(wx.BLACK, 1, wx.SOLID))
|
1822 | 1813 | dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
1823 | 1814 | self._rect = (x0, self.canvas._height-y0, x1-x0, -y1+y0)
|
1824 |
| - if wxc.is_phoenix: |
1825 |
| - dc.DrawRectangle(self._rect) |
1826 |
| - else: |
1827 |
| - dc.DrawRectangleRect(self._rect) |
| 1815 | + dc.DrawRectangle(self._rect) |
1828 | 1816 |
|
1829 | 1817 | def remove_rubberband(self, dc=None):
|
1830 | 1818 | if not self._rect:
|
@@ -1872,13 +1860,10 @@ def OnPrintPage(self, page):
|
1872 | 1860 | self.canvas.draw()
|
1873 | 1861 |
|
1874 | 1862 | dc = self.GetDC()
|
1875 |
| - (ppw, pph) = self.GetPPIPrinter() # printer's pixels per in |
1876 |
| - (pgw, pgh) = self.GetPageSizePixels() # page size in pixels |
1877 |
| - (dcw, dch) = dc.GetSize() |
1878 |
| - if wxc.is_phoenix: |
1879 |
| - (grw, grh) = self.canvas.GetSize() |
1880 |
| - else: |
1881 |
| - (grw, grh) = self.canvas.GetSizeTuple() |
| 1863 | + ppw, pph = self.GetPPIPrinter() # printer's pixels per in |
| 1864 | + pgw, pgh = self.GetPageSizePixels() # page size in pixels |
| 1865 | + dcw, dch = dc.GetSize() |
| 1866 | + grw, grh = self.canvas.GetSize() |
1882 | 1867 |
|
1883 | 1868 | # save current figure dpi resolution and bg color,
|
1884 | 1869 | # so that we can temporarily set them to the dpi of
|
|
0 commit comments