diff --git a/doc/api/next_api_changes/behavior/22013-AL.rst b/doc/api/next_api_changes/behavior/22013-AL.rst new file mode 100644 index 000000000000..c46b9ab7e488 --- /dev/null +++ b/doc/api/next_api_changes/behavior/22013-AL.rst @@ -0,0 +1,5 @@ +``FigureFrameWx.sizer`` +~~~~~~~~~~~~~~~~~~~~~~~ +... has been removed. The frame layout is no longer based on a sizer, as the +canvas is now the sole child widget; the toolbar is now a regular toolbar +added using ``SetToolBar``. diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index a7f35368a0a5..581f67bd802c 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -898,37 +898,25 @@ def __init__(self, num, fig, *, canvas_class=None): "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() - self.sizer = wx.BoxSizer(wx.VERTICAL) - self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND) - # By adding toolbar in sizer, we are able to put it at the bottom - # of the frame - so appearance is closer to GTK version self.figmgr = FigureManagerWx(self.canvas, num, self) self.toolbar = self._get_toolbar() - if self.figmgr.toolmanager: backend_tools.add_tools_to_manager(self.figmgr.toolmanager) if self.toolbar: backend_tools.add_tools_to_container(self.toolbar) - if self.toolbar is not None: - self.toolbar.Realize() - # On Windows platform, default window size is incorrect, so set - # toolbar width to figure width. - tw, th = self.toolbar.GetSize() - fw, fh = self.canvas.GetSize() - # By adding toolbar in sizer, we are able to put it at the bottom - # of the frame - so appearance is closer to GTK version. - self.toolbar.SetSize(wx.Size(fw, th)) - self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) - self.SetSizer(self.sizer) - self.Fit() + self.SetToolBar(self.toolbar) + # On Windows, canvas sizing must occur after toolbar addition; + # otherwise the toolbar further resizes the canvas. + w, h = map(math.ceil, fig.bbox.size) + self.canvas.SetInitialSize(wx.Size(w, h)) self.canvas.SetMinSize((2, 2)) + self.canvas.SetFocus() + + self.Fit() self.Bind(wx.EVT_CLOSE, self._on_close) @@ -966,10 +954,6 @@ def _on_close(self, event): # Carry on with close event propagation, frame & children destruction event.Skip() - def GetToolBar(self): - """Override wxFrame::GetToolBar as we don't have managed toolbar""" - return self.toolbar - def Destroy(self, *args, **kwargs): try: self.canvas.mpl_disconnect(self.toolbar._id_drag) @@ -1049,9 +1033,9 @@ def set_window_title(self, title): def resize(self, width, height): # docstring inherited - self.canvas.SetInitialSize( - wx.Size(math.ceil(width), math.ceil(height))) - self.window.GetSizer().Fit(self.window) + # Directly using SetClientSize doesn't handle the toolbar on Windows. + self.window.SetSize(self.window.ClientToWindowSize(wx.Size( + math.ceil(width), math.ceil(height)))) def _load_bitmap(filename): @@ -1073,8 +1057,8 @@ def _set_frame_icon(frame): class NavigationToolbar2Wx(NavigationToolbar2, wx.ToolBar): - def __init__(self, canvas, coordinates=True): - wx.ToolBar.__init__(self, canvas.GetParent(), -1) + def __init__(self, canvas, coordinates=True, *, style=wx.TB_BOTTOM): + wx.ToolBar.__init__(self, canvas.GetParent(), -1, style=style) if 'wxMac' in wx.PlatformInfo: self.SetToolBitmapSize((24, 24)) @@ -1202,7 +1186,7 @@ def set_history_buttons(self): # tools for matplotlib.backend_managers.ToolManager: class ToolbarWx(ToolContainerBase, wx.ToolBar): - def __init__(self, toolmanager, parent, style=wx.TB_HORIZONTAL): + def __init__(self, toolmanager, parent, style=wx.TB_BOTTOM): ToolContainerBase.__init__(self, toolmanager) wx.ToolBar.__init__(self, parent, -1, style=style) self._space = self.AddStretchableSpace()