Propagate InformFirstDirection() calls to wxBoxSizer children

InformFirstDirection() is required to let wxWrapSizer calculate its best
height from its current width (or vice versa, but usually in this
sense), but it only worked if wxWrapSizer was an immediate child of
another size doing layout but not if wxWrapSizer was inside another
wxBoxSizer which was contained in a top-level sizer.

Explicitly forward calls to InformFirstDirection() to wxBoxSizer
children to fix this and make wxWrapSizers nested in wxBoxSizer work.

Note that there are still many problems in this code, including but not
limited to:

- Doing this forwarding for the sizer minor direction only.
- Not passing the correct value of "availableOtherDir".
- Still calling InformFirstDirection() from RecalcSizes(), when it's too
  late to change the min size returned by CalcMin().
- Inconsistency: wxGridSizer calls InformFirstDirection() from its
  CalcMin(), wxFlexGridSizer calls it from its RecalcSizes(),
  wxGridBagSizer doesn't call it at all.

All this size-in-first-direction logic really needs to be completely
reviewed, but for now at least make wxWrapSizer inside a wxBoxSizer work
as well, or as badly, as wxWrapSizer on its own.
This commit is contained in:
Vadim Zeitlin
2018-10-21 15:58:33 +02:00
parent 35a9f134cc
commit e397d5d825
2 changed files with 33 additions and 0 deletions

View File

@@ -619,6 +619,10 @@ public:
// Inform sizer about the first direction that has been decided (by parent item) // Inform sizer about the first direction that has been decided (by parent item)
// Returns true if it made use of the information (and recalculated min size) // Returns true if it made use of the information (and recalculated min size)
//
// Note that while this method doesn't do anything by default, it should
// almost always be overridden in the derived classes and should have been
// pure virtual if not for backwards compatibility constraints.
virtual bool InformFirstDirection( int WXUNUSED(direction), int WXUNUSED(size), int WXUNUSED(availableOtherDir) ) virtual bool InformFirstDirection( int WXUNUSED(direction), int WXUNUSED(size), int WXUNUSED(availableOtherDir) )
{ return false; } { return false; }
@@ -958,6 +962,10 @@ public:
virtual wxSize CalcMin() wxOVERRIDE; virtual wxSize CalcMin() wxOVERRIDE;
virtual void RecalcSizes() wxOVERRIDE; virtual void RecalcSizes() wxOVERRIDE;
virtual bool InformFirstDirection(int direction,
int size,
int availableOtherDir) wxOVERRIDE;
protected: protected:
// Only overridden to perform extra debugging checks. // Only overridden to perform extra debugging checks.
virtual wxSizerItem *DoInsert(size_t index, wxSizerItem *item) wxOVERRIDE; virtual wxSizerItem *DoInsert(size_t index, wxSizerItem *item) wxOVERRIDE;

View File

@@ -2544,6 +2544,31 @@ wxSize wxBoxSizer::CalcMin()
return m_calculatedMinSize; return m_calculatedMinSize;
} }
bool
wxBoxSizer::InformFirstDirection(int direction, int size, int availableOtherDir)
{
// In principle, we could propagate the information about the size in the
// sizer major direction too, but this would require refactoring CalcMin()
// to determine the actual sizes all our items would have with the given
// size and we don't do this yet, so for now handle only the simpler case
// of informing all our items about their size in the orthogonal direction.
if ( direction == GetOrientation() )
return false;
bool didUse = false;
for ( wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
node;
node = node->GetNext() )
{
didUse |= node->GetData()->InformFirstDirection(direction,
size,
availableOtherDir);
}
return didUse;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// wxStaticBoxSizer // wxStaticBoxSizer
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------