From 39706e4db0acf0a305cd70516258a45b100fb27b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 11 Apr 2023 16:48:58 +0200 Subject: [PATCH] Use wxBaseArray instead of object arrays in wxAuiManager This is similar to the previous commit and replaces some object arrays with arrays of objects, as we need to keep providing more or less the same API for accessing these arrays because they can be used from the application code, even if they're not formally part of our public API. Also adjust m_actionPart when removing parts from m_uiParts. This seems to have been always necessary when deleting the part corresponding to the action one, but now is also needed when deleting any previous parts too. --- include/wx/aui/framemanager.h | 17 +++++++++------ src/aui/framemanager.cpp | 41 ++++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/include/wx/aui/framemanager.h b/include/wx/aui/framemanager.h index 1e6ff1c577..3f59b24a30 100644 --- a/include/wx/aui/framemanager.h +++ b/include/wx/aui/framemanager.h @@ -128,13 +128,11 @@ class wxAuiDockInfo; class wxAuiDockArt; class wxAuiManagerEvent; -#ifndef SWIG -WX_DECLARE_USER_EXPORTED_OBJARRAY(wxAuiDockInfo, wxAuiDockInfoArray, WXDLLIMPEXP_AUI); -WX_DECLARE_USER_EXPORTED_OBJARRAY(wxAuiDockUIPart, wxAuiDockUIPartArray, WXDLLIMPEXP_AUI); -WX_DECLARE_USER_EXPORTED_OBJARRAY(wxAuiPaneInfo, wxAuiPaneInfoArray, WXDLLIMPEXP_AUI); -WX_DEFINE_USER_EXPORTED_ARRAY_PTR(wxAuiPaneInfo*, wxAuiPaneInfoPtrArray, class WXDLLIMPEXP_AUI); -WX_DEFINE_USER_EXPORTED_ARRAY_PTR(wxAuiDockInfo*, wxAuiDockInfoPtrArray, class WXDLLIMPEXP_AUI); -#endif // SWIG +using wxAuiDockUIPartArray = wxBaseArray; +using wxAuiDockInfoArray = wxBaseArray; +using wxAuiPaneInfoArray = wxBaseArray; +using wxAuiDockInfoPtrArray = wxBaseArray; +using wxAuiPaneInfoPtrArray = wxBaseArray; extern WXDLLIMPEXP_AUI wxAuiDockInfo wxAuiNullDockInfo; extern WXDLLIMPEXP_AUI wxAuiPaneInfo wxAuiNullPaneInfo; @@ -615,6 +613,11 @@ protected: void* m_reserved; +private: + // Return the index in m_uiParts corresponding to the current value of + // m_actionPart. If m_actionPart is null, returns wxNOT_FOUND. + int GetActionPartIndex() const; + #ifndef SWIG wxDECLARE_EVENT_TABLE(); wxDECLARE_CLASS(wxAuiManager); diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index c2fbe3ffbc..d90a07a763 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -42,11 +42,6 @@ WX_CHECK_BUILD_OPTIONS("wxAUI") -#include "wx/arrimpl.cpp" -WX_DEFINE_OBJARRAY(wxAuiDockUIPartArray) -WX_DEFINE_OBJARRAY(wxAuiDockInfoArray) -WX_DEFINE_OBJARRAY(wxAuiPaneInfoArray) - wxAuiPaneInfo wxAuiNullPaneInfo; wxAuiDockInfo wxAuiNullDockInfo; wxDEFINE_EVENT( wxEVT_AUI_PANE_BUTTON, wxAuiManagerEvent ); @@ -628,6 +623,20 @@ wxAuiManager::~wxAuiManager() delete m_art; } +int wxAuiManager::GetActionPartIndex() const +{ + int n = 0; + for ( const auto& uiPart : m_uiParts ) + { + if ( &uiPart == m_actionPart ) + return n; + + ++n; + } + + return wxNOT_FOUND; +} + void wxAuiManager::OnSysColourChanged(wxSysColourChangedEvent& event) { m_art->UpdateColoursFromSystem(); @@ -1239,12 +1248,27 @@ bool wxAuiManager::DetachPane(wxWindow* window) // just in case the caller doesn't call Update() immediately after // the DetachPane() call. This prevets obscure crashes which would // happen at window repaint if the caller forgets to call Update() + int actionPartIndex = GetActionPartIndex(); int pi, part_count; for (pi = 0, part_count = (int)m_uiParts.GetCount(); pi < part_count; ++pi) { wxAuiDockUIPart& part = m_uiParts.Item(pi); if (part.pane == &p) { + if (actionPartIndex != wxNOT_FOUND) + { + if (pi == actionPartIndex) + { + // We're removing the action part, so invalidate it. + actionPartIndex = wxNOT_FOUND; + } + else if (pi < actionPartIndex) + { + // Just adjust the action part index. + actionPartIndex--; + } + } + m_uiParts.RemoveAt(pi); part_count--; pi--; @@ -1252,6 +1276,11 @@ bool wxAuiManager::DetachPane(wxWindow* window) } } + // Update m_actionPart pointer too to ensure that it remains valid. + m_actionPart = actionPartIndex == wxNOT_FOUND + ? nullptr + : &m_uiParts.Item(actionPartIndex); + m_panes.RemoveAt(i); return true; } @@ -4542,7 +4571,7 @@ void wxAuiManager::OnMotion(wxMouseEvent& event) if (m_currentDragItem != -1) m_actionPart = & (m_uiParts.Item(m_currentDragItem)); else - m_currentDragItem = m_uiParts.Index(* m_actionPart); + m_currentDragItem = GetActionPartIndex(); if (m_actionPart) {