|
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