From c8e3742da52768ce2ecf1717166820161a96e7dd Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Thu, 16 Dec 2021 19:42:10 +0100 Subject: [PATCH] Simplify canvas class control in FigureFrameWx. Remember that the wx backends have a slightly different init order because the canvas cannot be instantiated *before* the containing window (a "frame" in wx parlance), so previously different wx backends implemented different frame subclasses so that each of them can instantiate different canvas subclasses. Instead of doing that (and having to assign them to the private `_frame_class` attribute, which is a problem e.g. for third-party backends such as mplcairo), directly pass the canvas class as a parameter to FigureFrameWx. --- doc/api/next_api_changes/behavior/21983-AL.rst | 8 ++++++++ lib/matplotlib/backends/backend_wx.py | 17 +++++++++++++---- lib/matplotlib/backends/backend_wxagg.py | 4 +++- lib/matplotlib/backends/backend_wxcairo.py | 4 +++- 4 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 doc/api/next_api_changes/behavior/21983-AL.rst diff --git a/doc/api/next_api_changes/behavior/21983-AL.rst b/doc/api/next_api_changes/behavior/21983-AL.rst new file mode 100644 index 000000000000..d287756ec2d4 --- /dev/null +++ b/doc/api/next_api_changes/behavior/21983-AL.rst @@ -0,0 +1,8 @@ +``FigureFrameWx`` constructor, subclasses, and ``get_canvas`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The ``FigureCanvasWx`` constructor gained a *canvas_class* keyword-only +parameter which specifies the canvas class that should be used. This +parameter will become required in the future. The ``get_canvas`` method, +which was previously used to customize canvas creation, is deprecated. The +``FigureFrameWxAgg`` and ``FigureFrameWxCairo`` subclasses, which overrode +``get_canvas``, are deprecated. diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index f8d867caf88b..ebacb94b9095 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -892,7 +892,7 @@ def _print_image(self, filetype, filename): class FigureFrameWx(wx.Frame): - def __init__(self, num, fig): + def __init__(self, num, fig, *, canvas_class=None): # On non-Windows platform, explicitly set the position - fix # positioning bug on some Linux platforms if wx.Platform == '__WXMSW__': @@ -905,7 +905,15 @@ def __init__(self, num, fig): self.num = num _set_frame_icon(self) - self.canvas = self.get_canvas(fig) + # The parameter will become required after the deprecation elapses. + if canvas_class is not None: + self.canvas = canvas_class(self, -1, fig) + else: + _api.warn_deprecated( + "3.6", message="The canvas_class parameter will become " + "required after the deprecation period starting in Matplotlib " + "%(since)s elapses.") + self.canvas = self.get_canvas(fig) w, h = map(math.ceil, fig.bbox.size) self.canvas.SetInitialSize(wx.Size(w, h)) self.canvas.SetFocus() @@ -953,6 +961,8 @@ def _get_toolbar(self): toolbar = None return toolbar + @_api.deprecated( + "3.6", alternative="the canvas_class constructor parameter") def get_canvas(self, fig): return FigureCanvasWx(self, -1, fig) @@ -1393,7 +1403,6 @@ def trigger(self, *args, **kwargs): class _BackendWx(_Backend): FigureCanvas = FigureCanvasWx FigureManager = FigureManagerWx - _frame_class = FigureFrameWx @classmethod def new_figure_manager(cls, num, *args, **kwargs): @@ -1410,7 +1419,7 @@ def new_figure_manager(cls, num, *args, **kwargs): @classmethod def new_figure_manager_given_figure(cls, num, figure): - frame = cls._frame_class(num, figure) + frame = FigureFrameWx(num, figure, canvas_class=cls.FigureCanvas) figmgr = frame.get_figure_manager() if mpl.is_interactive(): figmgr.frame.Show() diff --git a/lib/matplotlib/backends/backend_wxagg.py b/lib/matplotlib/backends/backend_wxagg.py index c88a59979daa..67cf58c4408d 100644 --- a/lib/matplotlib/backends/backend_wxagg.py +++ b/lib/matplotlib/backends/backend_wxagg.py @@ -1,11 +1,14 @@ import wx +from .. import _api from .backend_agg import FigureCanvasAgg from .backend_wx import ( _BackendWx, _FigureCanvasWxBase, FigureFrameWx, NavigationToolbar2Wx as NavigationToolbar2WxAgg) +@_api.deprecated( + "3.6", alternative="FigureFrameWx(..., canvas_class=FigureCanvasWxAgg)") class FigureFrameWxAgg(FigureFrameWx): def get_canvas(self, fig): return FigureCanvasWxAgg(self, -1, fig) @@ -56,4 +59,3 @@ def _rgba_to_wx_bitmap(rgba): @_BackendWx.export class _BackendWxAgg(_BackendWx): FigureCanvas = FigureCanvasWxAgg - _frame_class = FigureFrameWxAgg diff --git a/lib/matplotlib/backends/backend_wxcairo.py b/lib/matplotlib/backends/backend_wxcairo.py index 0ff10d9b27d7..21d2e5d0d60d 100644 --- a/lib/matplotlib/backends/backend_wxcairo.py +++ b/lib/matplotlib/backends/backend_wxcairo.py @@ -1,11 +1,14 @@ import wx.lib.wxcairo as wxcairo +from .. import _api from .backend_cairo import cairo, FigureCanvasCairo from .backend_wx import ( _BackendWx, _FigureCanvasWxBase, FigureFrameWx, NavigationToolbar2Wx as NavigationToolbar2WxCairo) +@_api.deprecated( + "3.6", alternative="FigureFrameWx(..., canvas_class=FigureCanvasWxCairo)") class FigureFrameWxCairo(FigureFrameWx): def get_canvas(self, fig): return FigureCanvasWxCairo(self, -1, fig) @@ -36,4 +39,3 @@ def draw(self, drawDC=None): @_BackendWx.export class _BackendWxCairo(_BackendWx): FigureCanvas = FigureCanvasWxCairo - _frame_class = FigureFrameWxCairo