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.
This commit is contained in:
Vadim Zeitlin 2023-04-11 16:48:58 +02:00
parent bceace12b5
commit 39706e4db0
2 changed files with 45 additions and 13 deletions

View file

@ -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<wxAuiDockUIPart>;
using wxAuiDockInfoArray = wxBaseArray<wxAuiDockInfo>;
using wxAuiPaneInfoArray = wxBaseArray<wxAuiPaneInfo>;
using wxAuiDockInfoPtrArray = wxBaseArray<wxAuiDockInfo*>;
using wxAuiPaneInfoPtrArray = wxBaseArray<wxAuiPaneInfo*>;
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);

View file

@ -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)
{