Respect item max sizes in wxBoxSizer.
Don't give more space than the max size, if set, to wxBoxSizer elements. Closes #11497. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72345 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -534,6 +534,7 @@ All:
|
||||
|
||||
All (GUI):
|
||||
|
||||
- Respect window max size in wxBoxSizer (Nathan Ridge).
|
||||
- Add possibility to hide and show again wxRibbonBar pages (wxBen).
|
||||
- Add expand/collapse button to wxRibbonBar (rakeshthp).
|
||||
- Fix item data access in wxDataViewListCtrl (Kry).
|
||||
|
@@ -311,6 +311,10 @@ public:
|
||||
{ return m_minSize; }
|
||||
wxSize GetMinSizeWithBorder() const;
|
||||
|
||||
wxSize GetMaxSize() const
|
||||
{ return IsWindow() ? m_window->GetMaxSize() : wxDefaultSize; }
|
||||
wxSize GetMaxSizeWithBorder() const;
|
||||
|
||||
void SetMinSize(const wxSize& size)
|
||||
{
|
||||
if ( IsWindow() )
|
||||
|
@@ -417,6 +417,10 @@ wxSize wxSizerItem::GetMinSizeWithBorder() const
|
||||
return AddBorderToSize(m_minSize);
|
||||
}
|
||||
|
||||
wxSize wxSizerItem::GetMaxSizeWithBorder() const
|
||||
{
|
||||
return AddBorderToSize(GetMaxSize());
|
||||
}
|
||||
|
||||
void wxSizerItem::SetDimension( const wxPoint& pos_, const wxSize& size_ )
|
||||
{
|
||||
@@ -2226,6 +2230,66 @@ void wxBoxSizer::RecalcSizes()
|
||||
nonFixedSpaceChanged = true;
|
||||
}
|
||||
|
||||
// Similar to the previous loop, but dealing with items whose max size
|
||||
// is less than what we would allocate to them taking their proportion
|
||||
// into account.
|
||||
nonFixedSpaceChanged = false;
|
||||
for ( i = m_children.begin(), n = 0; ; ++i, ++n )
|
||||
{
|
||||
if ( nonFixedSpaceChanged )
|
||||
{
|
||||
i = m_children.begin();
|
||||
n = 0;
|
||||
nonFixedSpaceChanged = false;
|
||||
}
|
||||
|
||||
// check for the end of the loop only after the check above as
|
||||
// otherwise we wouldn't do another pass if the last child resulted
|
||||
// in non fixed space reduction
|
||||
if ( i == m_children.end() )
|
||||
break;
|
||||
|
||||
wxSizerItem * const item = *i;
|
||||
|
||||
if ( !item->IsShown() )
|
||||
continue;
|
||||
|
||||
// don't check the item which we had already dealt with during a
|
||||
// previous pass (this is more than an optimization, the code
|
||||
// wouldn't work correctly if we kept adjusting for the same item
|
||||
// over and over again)
|
||||
if ( majorSizes[n] != wxDefaultCoord )
|
||||
continue;
|
||||
|
||||
wxCoord maxMajor = GetSizeInMajorDir(item->GetMaxSizeWithBorder());
|
||||
|
||||
// must be nonzero, fixed-size items were dealt with in previous loop
|
||||
const int propItem = item->GetProportion();
|
||||
|
||||
// is the desired size of this item small enough?
|
||||
if ( maxMajor < 0 ||
|
||||
(remaining*propItem)/totalProportion <= maxMajor )
|
||||
{
|
||||
// yes, it is, we'll determine the real size of this
|
||||
// item later, for now just leave it as wxDefaultCoord
|
||||
continue;
|
||||
}
|
||||
|
||||
// the proportion of this item won't count, it has
|
||||
// effectively become fixed
|
||||
totalProportion -= propItem;
|
||||
|
||||
// we can already allocate space for this item
|
||||
majorSizes[n] = maxMajor;
|
||||
|
||||
// change the amount of the space remaining to the other items,
|
||||
// as this can result in not being able to satisfy their
|
||||
// proportions any more we will need to redo another loop
|
||||
// iteration
|
||||
remaining -= maxMajor;
|
||||
|
||||
nonFixedSpaceChanged = true;
|
||||
}
|
||||
|
||||
// Last by one pass: distribute the remaining space among the non-fixed
|
||||
// items whose size weren't fixed yet according to their proportions.
|
||||
@@ -2277,8 +2341,15 @@ void wxBoxSizer::RecalcSizes()
|
||||
// its minimal size which is bad but better than not showing parts
|
||||
// of the window at all
|
||||
minorSize = totalMinorSize;
|
||||
|
||||
// do not allow the size in the minor direction to grow beyond the max
|
||||
// size of the item in the minor direction
|
||||
const wxCoord maxMinorSize = GetSizeInMinorDir(item->GetMaxSizeWithBorder());
|
||||
if ( maxMinorSize >= 0 && minorSize > maxMinorSize )
|
||||
minorSize = maxMinorSize;
|
||||
}
|
||||
else if ( flag & (IsVertical() ? wxALIGN_RIGHT : wxALIGN_BOTTOM) )
|
||||
|
||||
if ( flag & (IsVertical() ? wxALIGN_RIGHT : wxALIGN_BOTTOM) )
|
||||
{
|
||||
PosInMinorDir(posChild) += totalMinorSize - minorSize;
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/app.h"
|
||||
#include "wx/sizer.h"
|
||||
#include "wx/listbox.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "asserthelper.h"
|
||||
@@ -41,11 +42,17 @@ private:
|
||||
CPPUNIT_TEST( Size1 );
|
||||
CPPUNIT_TEST( Size3 );
|
||||
CPPUNIT_TEST( CalcMin );
|
||||
CPPUNIT_TEST( BestSizeRespectsMaxSize );
|
||||
CPPUNIT_TEST( RecalcSizesRespectsMaxSize1 );
|
||||
CPPUNIT_TEST( RecalcSizesRespectsMaxSize2 );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void Size1();
|
||||
void Size3();
|
||||
void CalcMin();
|
||||
void BestSizeRespectsMaxSize();
|
||||
void RecalcSizesRespectsMaxSize1();
|
||||
void RecalcSizesRespectsMaxSize2();
|
||||
|
||||
wxWindow *m_win;
|
||||
wxSizer *m_sizer;
|
||||
@@ -298,3 +305,75 @@ void BoxSizerTestCase::CalcMin()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void BoxSizerTestCase::BestSizeRespectsMaxSize()
|
||||
{
|
||||
m_sizer->Clear();
|
||||
|
||||
const int maxWidth = 100;
|
||||
|
||||
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
wxListBox* listbox = new wxListBox(m_win, wxID_ANY);
|
||||
listbox->Append("some very very very very very very very very very very very long string");
|
||||
listbox->SetMaxSize(wxSize(maxWidth, -1));
|
||||
sizer->Add(listbox);
|
||||
|
||||
m_sizer->Add(sizer);
|
||||
m_win->Layout();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(maxWidth, listbox->GetSize().GetWidth());
|
||||
}
|
||||
|
||||
void BoxSizerTestCase::RecalcSizesRespectsMaxSize1()
|
||||
{
|
||||
m_sizer->Clear();
|
||||
|
||||
const int maxWidth = 100;
|
||||
|
||||
m_win->SetClientSize(300, 300);
|
||||
|
||||
wxSizer* sizer1 = new wxBoxSizer(wxVERTICAL);
|
||||
m_sizer->Add(sizer1);
|
||||
|
||||
wxListBox* listbox1 = new wxListBox(m_win, wxID_ANY);
|
||||
listbox1->Append("some very very very very very very very very very very very long string");
|
||||
sizer1->Add(listbox1);
|
||||
|
||||
wxSizer* sizer2 = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer1->Add(sizer2, wxSizerFlags().Expand());
|
||||
|
||||
wxListBox* listbox2 = new wxListBox(m_win, wxID_ANY);
|
||||
listbox2->Append("some string");
|
||||
listbox2->SetMaxSize(wxSize(100, -1));
|
||||
sizer2->Add(listbox2, wxSizerFlags().Proportion(1));
|
||||
|
||||
m_win->Layout();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(maxWidth, listbox2->GetSize().GetWidth());
|
||||
}
|
||||
|
||||
void BoxSizerTestCase::RecalcSizesRespectsMaxSize2()
|
||||
{
|
||||
m_sizer->Clear();
|
||||
|
||||
m_win->SetClientSize(300, 300);
|
||||
|
||||
wxSizer* sizer1 = new wxBoxSizer(wxVERTICAL);
|
||||
m_sizer->Add(sizer1, wxSizerFlags().Expand());
|
||||
|
||||
wxWindow* child1 = new wxWindow(m_win, wxID_ANY);
|
||||
sizer1->Add(child1, wxSizerFlags().Proportion(1));
|
||||
|
||||
wxWindow* child2 = new wxWindow(m_win, wxID_ANY);
|
||||
child2->SetMaxSize(wxSize(-1, 50));
|
||||
sizer1->Add(child2, wxSizerFlags().Proportion(1));
|
||||
|
||||
wxWindow* child3 = new wxWindow(m_win, wxID_ANY);
|
||||
sizer1->Add(child3, wxSizerFlags().Proportion(1));
|
||||
|
||||
m_win->Layout();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(125, child1->GetSize().GetHeight());
|
||||
CPPUNIT_ASSERT_EQUAL(50, child2->GetSize().GetHeight());
|
||||
CPPUNIT_ASSERT_EQUAL(125, child3->GetSize().GetHeight());
|
||||
}
|
||||
|
Reference in New Issue
Block a user