Merge branch 'sizer-cleanup'

Clean up and modernize sizer code without any real changes.

See #23291.
This commit is contained in:
Vadim Zeitlin 2023-02-23 18:09:34 +01:00
commit ef47a04769
3 changed files with 137 additions and 169 deletions

View file

@ -770,6 +770,9 @@ protected:
virtual wxSizerItem* DoInsert(size_t index, wxSizerItem *item);
private:
// Get the child item with the given index and assert if there is none.
wxSizerItemList::compatibility_iterator GetChildNode(size_t index) const;
wxDECLARE_CLASS(wxSizer);
};

View file

@ -858,6 +858,22 @@ wxSizerItem* wxSizer::DoInsert( size_t index, wxSizerItem *item )
return guard.Release();
}
wxSizerItemList::compatibility_iterator wxSizer::GetChildNode(size_t index) const
{
wxCHECK_MSG
(
index < m_children.GetCount(),
{},
wxString::Format
(
"Invalid sizer item child index %zu, sizer has only %zu elements.",
index, m_children.GetCount()
)
);
return m_children.Item( index );
}
void wxSizer::SetContainingWindow(wxWindow *win)
{
if ( win == m_containingWindow )
@ -867,11 +883,8 @@ void wxSizer::SetContainingWindow(wxWindow *win)
// set the same window for all nested sizers as well, they also are in the
// same window
for ( wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
node;
node = node->GetNext() )
for ( const wxSizerItem* item: m_children )
{
wxSizerItem *const item = node->GetData();
wxSizer *const sizer = item->GetSizer();
if ( sizer )
@ -913,13 +926,11 @@ bool wxSizer::Remove( wxSizer *sizer )
bool wxSizer::Remove( int index )
{
wxCHECK_MSG( index >= 0 && (size_t)index < m_children.GetCount(),
false,
wxT("Remove index is out of range") );
wxCHECK_MSG( index >= 0, false, wxT("Index must be positive") );
wxSizerItemList::compatibility_iterator node = m_children.Item( index );
wxCHECK_MSG( node, false, wxT("Failed to find child node") );
const auto node = GetChildNode(static_cast<size_t>(index));
if ( !node )
return false;
delete node->GetData();
m_children.Erase( node );
@ -972,13 +983,11 @@ bool wxSizer::Detach( wxWindow *window )
bool wxSizer::Detach( int index )
{
wxCHECK_MSG( index >= 0 && (size_t)index < m_children.GetCount(),
false,
wxT("Detach index is out of range") );
wxCHECK_MSG( index >= 0, false, wxT("Index must be positive") );
wxSizerItemList::compatibility_iterator node = m_children.Item( index );
wxCHECK_MSG( node, false, wxT("Failed to find child node") );
const auto node = GetChildNode(static_cast<size_t>(index));
if ( !node )
return false;
wxSizerItem *item = node->GetData();
@ -995,11 +1004,8 @@ bool wxSizer::Replace( wxWindow *oldwin, wxWindow *newwin, bool recursive )
wxASSERT_MSG( oldwin, wxT("Replacing null window") );
wxASSERT_MSG( newwin, wxT("Replacing with null window") );
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if (item->GetWindow() == oldwin)
{
item->AssignWindow(newwin);
@ -1011,8 +1017,6 @@ bool wxSizer::Replace( wxWindow *oldwin, wxWindow *newwin, bool recursive )
if (item->GetSizer()->Replace( oldwin, newwin, true ))
return true;
}
node = node->GetNext();
}
return false;
@ -1023,11 +1027,8 @@ bool wxSizer::Replace( wxSizer *oldsz, wxSizer *newsz, bool recursive )
wxASSERT_MSG( oldsz, wxT("Replacing null sizer") );
wxASSERT_MSG( newsz, wxT("Replacing with null sizer") );
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if (item->GetSizer() == oldsz)
{
item->AssignSizer(newsz);
@ -1038,8 +1039,6 @@ bool wxSizer::Replace( wxSizer *oldsz, wxSizer *newsz, bool recursive )
if (item->GetSizer()->Replace( oldsz, newsz, true ))
return true;
}
node = node->GetNext();
}
return false;
@ -1047,12 +1046,11 @@ bool wxSizer::Replace( wxSizer *oldsz, wxSizer *newsz, bool recursive )
bool wxSizer::Replace( size_t old, wxSizerItem *newitem )
{
wxCHECK_MSG( old < m_children.GetCount(), false, wxT("Replace index is out of range") );
wxCHECK_MSG( newitem, false, wxT("Replacing with null item") );
wxSizerItemList::compatibility_iterator node = m_children.Item( old );
wxCHECK_MSG( node, false, wxT("Failed to find child node") );
auto node = GetChildNode(old);
if ( !node )
return false;
wxSizerItem *item = node->GetData();
node->SetData(newitem);
@ -1071,14 +1069,10 @@ bool wxSizer::Replace( size_t old, wxSizerItem *newitem )
void wxSizer::Clear( bool delete_windows )
{
// First clear the ContainingSizer pointers
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( const wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if (item->IsWindow())
item->GetWindow()->SetContainingSizer( nullptr );
node = node->GetNext();
}
// Destroy the windows if needed
@ -1091,13 +1085,9 @@ void wxSizer::Clear( bool delete_windows )
void wxSizer::DeleteWindows()
{
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
item->DeleteWindows();
node = node->GetNext();
}
}
@ -1247,33 +1237,25 @@ bool wxSizer::DoSetItemMinSize( wxWindow *window, int width, int height )
// Is it our immediate child?
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if (item->GetWindow() == window)
{
item->SetMinSize( width, height );
return true;
}
node = node->GetNext();
}
// No? Search any subsizers we own then
node = m_children.GetFirst();
while (node)
for ( const wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if ( item->GetSizer() &&
item->GetSizer()->DoSetItemMinSize( window, width, height ) )
{
// A child sizer found the requested windw, exit.
return true;
}
node = node->GetNext();
}
return false;
@ -1285,33 +1267,25 @@ bool wxSizer::DoSetItemMinSize( wxSizer *sizer, int width, int height )
// Is it our immediate child?
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( const wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if (item->GetSizer() == sizer)
{
item->GetSizer()->DoSetMinSize( width, height );
return true;
}
node = node->GetNext();
}
// No? Search any subsizers we own then
node = m_children.GetFirst();
while (node)
for ( const wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if ( item->GetSizer() &&
item->GetSizer()->DoSetItemMinSize( sizer, width, height ) )
{
// A child found the requested sizer, exit.
return true;
}
node = node->GetNext();
}
return false;
@ -1319,9 +1293,9 @@ bool wxSizer::DoSetItemMinSize( wxSizer *sizer, int width, int height )
bool wxSizer::DoSetItemMinSize( size_t index, int width, int height )
{
wxSizerItemList::compatibility_iterator node = m_children.Item( index );
wxCHECK_MSG( node, false, wxT("Failed to find child node") );
const auto node = GetChildNode(index);
if ( !node )
return false;
wxSizerItem *item = node->GetData();
@ -1343,11 +1317,8 @@ wxSizerItem* wxSizer::GetItem( wxWindow *window, bool recursive )
{
wxASSERT_MSG( window, wxT("GetItem for null window") );
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if (item->GetWindow() == window)
{
return item;
@ -1358,8 +1329,6 @@ wxSizerItem* wxSizer::GetItem( wxWindow *window, bool recursive )
if (subitem)
return subitem;
}
node = node->GetNext();
}
return nullptr;
@ -1369,11 +1338,8 @@ wxSizerItem* wxSizer::GetItem( wxSizer *sizer, bool recursive )
{
wxASSERT_MSG( sizer, wxT("GetItem for null sizer") );
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if (item->GetSizer() == sizer)
{
return item;
@ -1384,8 +1350,6 @@ wxSizerItem* wxSizer::GetItem( wxSizer *sizer, bool recursive )
if (subitem)
return subitem;
}
node = node->GetNext();
}
return nullptr;
@ -1393,11 +1357,11 @@ wxSizerItem* wxSizer::GetItem( wxSizer *sizer, bool recursive )
wxSizerItem* wxSizer::GetItem( size_t index )
{
wxCHECK_MSG( index < m_children.GetCount(),
nullptr,
wxT("GetItem index is out of range") );
const auto node = GetChildNode(index);
if ( !node )
return nullptr;
return m_children.Item( index )->GetData();
return node->GetData();
}
wxSizerItem* wxSizer::GetItemById( int id, bool recursive )
@ -1405,11 +1369,8 @@ wxSizerItem* wxSizer::GetItemById( int id, bool recursive )
// This gets a sizer item by the id of the sizer item
// and NOT the id of a window if the item is a window.
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if (item->GetId() == id)
{
return item;
@ -1420,8 +1381,6 @@ wxSizerItem* wxSizer::GetItemById( int id, bool recursive )
if (subitem)
return subitem;
}
node = node->GetNext();
}
return nullptr;
@ -1468,22 +1427,18 @@ bool wxSizer::Show( size_t index, bool show)
void wxSizer::ShowItems( bool show )
{
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( wxSizerItem* item: m_children )
{
node->GetData()->Show( show );
node = node->GetNext();
item->Show( show );
}
}
bool wxSizer::AreAnyItemsShown() const
{
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( const wxSizerItem* item: m_children )
{
if ( node->GetData()->IsShown() )
if ( item->IsShown() )
return true;
node = node->GetNext();
}
return false;
@ -1491,16 +1446,12 @@ bool wxSizer::AreAnyItemsShown() const
bool wxSizer::IsShown( wxWindow *window ) const
{
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( const wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if (item->GetWindow() == window)
{
return item->IsShown();
}
node = node->GetNext();
}
wxFAIL_MSG( wxT("IsShown failed to find sizer item") );
@ -1510,16 +1461,12 @@ bool wxSizer::IsShown( wxWindow *window ) const
bool wxSizer::IsShown( wxSizer *sizer ) const
{
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( const wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
if (item->GetSizer() == sizer)
{
return item->IsShown();
}
node = node->GetNext();
}
wxFAIL_MSG( wxT("IsShown failed to find sizer item") );
@ -1529,11 +1476,11 @@ bool wxSizer::IsShown( wxSizer *sizer ) const
bool wxSizer::IsShown( size_t index ) const
{
wxCHECK_MSG( index < m_children.GetCount(),
false,
wxT("IsShown index is out of range") );
const auto node = GetChildNode(index);
if ( !node )
return false;
return m_children.Item( index )->GetData()->IsShown();
return node->GetData()->IsShown();
}
@ -1648,8 +1595,8 @@ int wxGridSizer::CalcRowsCols(int& nrows, int& ncols) const
void wxGridSizer::RepositionChildren(const wxSize& WXUNUSED(minSize))
{
int nitems, nrows, ncols;
if ( (nitems = CalcRowsCols(nrows, ncols)) == 0 )
int nrows, ncols;
if ( CalcRowsCols(nrows, ncols) == 0 )
return;
wxSize sz( GetSize() );
@ -1658,24 +1605,23 @@ void wxGridSizer::RepositionChildren(const wxSize& WXUNUSED(minSize))
int w = (sz.x - (ncols - 1) * m_hgap) / ncols;
int h = (sz.y - (nrows - 1) * m_vgap) / nrows;
int x = pt.x;
for (int c = 0; c < ncols; c++)
wxSizerItemList::const_iterator i = m_children.begin();
const wxSizerItemList::const_iterator end = m_children.end();
int y = pt.y;
for (int r = 0; r < nrows; r++)
{
int y = pt.y;
for (int r = 0; r < nrows; r++)
int x = pt.x;
for (int c = 0; c < ncols; c++, ++i)
{
int i = r * ncols + c;
if (i < nitems)
{
wxSizerItemList::compatibility_iterator node = m_children.Item( i );
if ( i == end )
return;
wxASSERT_MSG( node, wxT("Failed to find SizerItemList node") );
SetItemBounds(*i, x, y, w, h);
SetItemBounds( node->GetData(), x, y, w, h);
}
y = y + h + m_vgap;
x += w + m_hgap;
}
x = x + w + m_hgap;
y += h + m_vgap;
}
}
@ -1689,44 +1635,32 @@ wxSize wxGridSizer::CalcMin()
int w = 0;
int h = 0;
wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
while (node)
for ( wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
wxSize sz( item->CalcMin() );
w = wxMax( w, sz.x );
h = wxMax( h, sz.y );
node = node->GetNext();
}
// In case we have a nested sizer with a two step algo , give it
// a chance to adjust to that (we give it width component)
node = m_children.GetFirst();
bool didChangeMinSize = false;
while (node)
for ( wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
didChangeMinSize |= item->InformFirstDirection( wxHORIZONTAL, w, -1 );
node = node->GetNext();
}
// And redo iteration in case min size changed
if( didChangeMinSize )
{
node = m_children.GetFirst();
w = h = 0;
while (node)
for ( const wxSizerItem* item: m_children )
{
wxSizerItem *item = node->GetData();
wxSize sz( item->GetMinSizeWithBorder() );
w = wxMax( w, sz.x );
h = wxMax( h, sz.y );
node = node->GetNext();
}
}
@ -2738,13 +2672,9 @@ wxBoxSizer::InformFirstDirection(int direction, int size, int availableOtherDir)
bool didUse = false;
for ( wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
node;
node = node->GetNext() )
for ( wxSizerItem* item: m_children )
{
didUse |= node->GetData()->InformFirstDirection(direction,
size,
availableOtherDir);
didUse |= item->InformFirstDirection(direction, size, availableOtherDir);
}
return didUse;
@ -2793,12 +2723,8 @@ wxStaticBoxSizer::~wxStaticBoxSizer()
bool wxStaticBoxSizer::CheckForNonBoxChildren(wxSizer* sizer) const
{
for ( wxSizerItemList::compatibility_iterator node = sizer->GetChildren().GetFirst();
node;
node = node->GetNext() )
for ( const wxSizerItem* item: sizer->GetChildren() )
{
wxSizerItem *const item = node->GetData();
if ( wxWindow* const win = item->GetWindow() )
{
if ( CheckIfNonBoxChild(win) )

View file

@ -22,59 +22,79 @@
#include "asserthelper.h"
// ----------------------------------------------------------------------------
// test class
// test fixtures
// ----------------------------------------------------------------------------
class GridSizerTestCase
// Base class for the two fixtures below.
class GridSizerTestCaseBase
{
protected:
GridSizerTestCase();
~GridSizerTestCase();
explicit GridSizerTestCaseBase(wxGridSizer* sizer);
~GridSizerTestCaseBase();
// Clear the current sizer contents and add the specified windows to it,
// using the same flags for all of them.
void SetChildren(const wxVector<wxWindow*>& children,
const wxSizerFlags& flags);
wxWindow *m_win;
wxFlexGridSizer *m_sizer;
wxGridSizer* const m_sizerBase;
wxDECLARE_NO_COPY_CLASS(GridSizerTestCase);
wxDECLARE_NO_COPY_CLASS(GridSizerTestCaseBase);
};
class GridSizerTestCase : public GridSizerTestCaseBase
{
protected:
GridSizerTestCase()
: GridSizerTestCaseBase(m_sizer = new wxGridSizer(2))
{
}
wxGridSizer *m_sizer;
};
class FlexGridSizerTestCase : public GridSizerTestCaseBase
{
protected:
FlexGridSizerTestCase()
: GridSizerTestCaseBase(m_sizer = new wxFlexGridSizer(2))
{
}
wxFlexGridSizer *m_sizer;
};
// ----------------------------------------------------------------------------
// test initialization
// ----------------------------------------------------------------------------
GridSizerTestCase::GridSizerTestCase()
GridSizerTestCaseBase::GridSizerTestCaseBase(wxGridSizer* sizer)
: m_sizerBase(sizer)
{
m_win = new wxWindow(wxTheApp->GetTopWindow(), wxID_ANY);
m_win->SetClientSize(127, 35);
m_sizer = new wxFlexGridSizer(2);
m_win->SetSizer(m_sizer);
m_win->SetSizer(m_sizerBase);
}
GridSizerTestCase::~GridSizerTestCase()
GridSizerTestCaseBase::~GridSizerTestCaseBase()
{
delete m_win;
m_win = nullptr;
m_sizer = nullptr;
}
// ----------------------------------------------------------------------------
// helpers
// ----------------------------------------------------------------------------
void GridSizerTestCase::SetChildren(const wxVector<wxWindow*>& children,
const wxSizerFlags& flags)
void GridSizerTestCaseBase::SetChildren(const wxVector<wxWindow*>& children,
const wxSizerFlags& flags)
{
m_sizer->Clear();
m_sizerBase->Clear();
for ( wxVector<wxWindow*>::const_iterator i = children.begin();
i != children.end();
++i )
{
m_sizer->Add(*i, flags);
m_sizerBase->Add(*i, flags);
}
m_win->Layout();
@ -87,6 +107,25 @@ void GridSizerTestCase::SetChildren(const wxVector<wxWindow*>& children,
TEST_CASE_METHOD(GridSizerTestCase,
"wxGridSizer::Layout",
"[grid-sizer][sizer]")
{
const wxSize sizeTotal = m_win->GetClientSize();
const wxSize sizeChild(sizeTotal.x / 2, sizeTotal.y / 2);
wxVector<wxWindow*> children;
for ( int n = 0; n < 3; n++ )
{
children.push_back(new wxWindow(m_win, wxID_ANY));
}
SetChildren(children, wxSizerFlags().Expand());
CHECK( children[0]->GetRect() == wxRect(wxPoint(0, 0), sizeChild) );
CHECK( children[1]->GetRect() == wxRect(wxPoint(sizeChild.x, 0), sizeChild) );
CHECK( children[2]->GetRect() == wxRect(wxPoint(0, sizeChild.y), sizeChild) );
}
TEST_CASE_METHOD(FlexGridSizerTestCase,
"wxFlexGridSizer::Layout",
"[grid-sizer][sizer]")
{
const wxSize sizeTotal = m_win->GetClientSize();
const wxSize sizeChild(sizeTotal.x / 4, sizeTotal.y / 4);
@ -180,8 +219,8 @@ TEST_CASE_METHOD(GridSizerTestCase,
);
}
TEST_CASE_METHOD(GridSizerTestCase,
"wxGridSizer::GrowMode",
TEST_CASE_METHOD(FlexGridSizerTestCase,
"wxFlexGridSizer::GrowMode",
"[grid-sizer][sizer]")
{
wxVector<wxWindow*> children;