From 62f6be4448a1a8ba6b3ddc920df7c0957b7b1f31 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 28 Dec 2009 16:18:37 +0000 Subject: [PATCH] Ensure that frame is re-laid out when its toolbar is deleted. The code in wxFrameBase::SetToolBar() didn't work correctly when toolbar was unset using SetToolBar(NULL) because the frame toolbar pointer was reset before layout was done resulting in the frame not recognizing its (still existing) toolbar child as one of its bars and so nothing was done at all when the frame had a single child, as in the toolbar sample. Correct this by carefully ensuring that the toolbar pointer is still set at the moment of the layout but hide the toolbar to ensure that no place is allocated for it. Also mention that it is not necessary to call SetToolBar(NULL) at all if the toolbar is being deleted anyhow in the sample as toolbar does this itself in its destructor. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63007 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- samples/toolbar/toolbar.cpp | 6 ++++-- src/common/framecmn.cpp | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/samples/toolbar/toolbar.cpp b/samples/toolbar/toolbar.cpp index 5215196180..7d0a678acd 100644 --- a/samples/toolbar/toolbar.cpp +++ b/samples/toolbar/toolbar.cpp @@ -706,9 +706,11 @@ void MyFrame::OnToggleToolbar(wxCommandEvent& WXUNUSED(event)) } else { + // notice that there is no need to call SetToolBar(NULL) here (although + // this it is harmless to do and it must be called if you do not delete + // the toolbar but keep it for later reuse), just delete the toolbar + // directly and it will reset the associated frame toolbar pointer delete tbar; - - SetToolBar(NULL); } } diff --git a/src/common/framecmn.cpp b/src/common/framecmn.cpp index 7cbe913304..f83d3e488b 100644 --- a/src/common/framecmn.cpp +++ b/src/common/framecmn.cpp @@ -500,15 +500,40 @@ wxToolBar* wxFrameBase::OnCreateToolBar(long style, void wxFrameBase::SetToolBar(wxToolBar *toolbar) { - bool hadBar = m_frameToolBar != NULL; - m_frameToolBar = toolbar; - - if ( (m_frameToolBar != NULL) != hadBar ) + if ( (toolbar != NULL) != (m_frameToolBar != NULL) ) { - PositionToolBar(); + // the toolbar visibility must have changed so we need to both position + // the toolbar itself (if it appeared) and to relayout the frame + // contents in any case + + if ( toolbar ) + { + // we need to assign it to m_frameToolBar for PositionToolBar() to + // do anything + m_frameToolBar = toolbar; + PositionToolBar(); + } + //else: tricky: do not reset m_frameToolBar yet as otherwise DoLayout() + // wouldn't recognize the (still existing) toolbar as one of our + // bars and wouldn't layout the single child of the frame correctly + + + // and this is even more tricky: we want DoLayout() to recognize the + // old toolbar for the purpose of not counting it among our non-bar + // children but we don't want to reserve any more space for it so we + // temporarily hide it + if ( m_frameToolBar ) + m_frameToolBar->Hide(); DoLayout(); + + if ( m_frameToolBar ) + m_frameToolBar->Show(); } + + // this might have been already done above but it's simpler to just always + // do it unconditionally instead of testing for whether we already did it + m_frameToolBar = toolbar; } #endif // wxUSE_TOOLBAR -- 2.45.2