diff --git a/interface/wx/window.h b/interface/wx/window.h index 7b32e9c5c5..29300d796d 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -845,6 +845,12 @@ public: convenient, DoGetBestClientSize() when writing your own custom window class to change the value returned by this public non-virtual method. + Notice that the best size respects the minimal and maximal size + explicitly set for the window, if any. So even if some window believes + that it needs 200 pixels horizontally, calling SetMaxSize() with a + width of 100 would ensure that GetBestSize() returns the width of at + most 100 pixels. + @see CacheBestSize(), @ref overview_windowsizing */ wxSize GetBestSize() const; diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 031712592b..ae072ece15 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -906,14 +906,19 @@ wxSize wxWindowBase::GetBestSize() const // it to be used wxSize size = DoGetBestClientSize(); if ( size != wxDefaultSize ) - { size += DoGetBorderSize(); + else + size = DoGetBestSize(); - CacheBestSize(size); - return size; - } + // Ensure that the best size is at least as large as min size. + size.IncTo(GetMinSize()); - return DoGetBestSize(); + // And not larger than max size. + size.DecToIfSpecified(GetMaxSize()); + + // Finally cache result and return. + CacheBestSize(size); + return size; } int wxWindowBase::GetBestHeight(int width) const @@ -938,12 +943,16 @@ void wxWindowBase::SetMinSize(const wxSize& minSize) { m_minWidth = minSize.x; m_minHeight = minSize.y; + + InvalidateBestSize(); } void wxWindowBase::SetMaxSize(const wxSize& maxSize) { m_maxWidth = maxSize.x; m_maxHeight = maxSize.y; + + InvalidateBestSize(); } void wxWindowBase::SetInitialSize(const wxSize& size) diff --git a/tests/window/setsize.cpp b/tests/window/setsize.cpp index c1fd6f8535..b720b79335 100644 --- a/tests/window/setsize.cpp +++ b/tests/window/setsize.cpp @@ -40,10 +40,25 @@ private: CPPUNIT_TEST_SUITE( SetSizeTestCase ); CPPUNIT_TEST( SetSize ); CPPUNIT_TEST( SetSizeLessThanMinSize ); + CPPUNIT_TEST( BestSize ); CPPUNIT_TEST_SUITE_END(); void SetSize(); void SetSizeLessThanMinSize(); + void BestSize(); + + // Helper class overriding DoGetBestSize() for testing purposes. + class MyWindow : public wxWindow + { + public: + MyWindow(wxWindow* parent) + : wxWindow(parent, wxID_ANY) + { + } + + protected: + virtual wxSize DoGetBestSize() const { return wxSize(50, 250); } + }; wxWindow *m_win; @@ -62,7 +77,7 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SetSizeTestCase, "SetSizeTestCase" ); void SetSizeTestCase::setUp() { - m_win = new wxWindow(wxTheApp->GetTopWindow(), wxID_ANY); + m_win = new MyWindow(wxTheApp->GetTopWindow()); } void SetSizeTestCase::tearDown() @@ -91,3 +106,13 @@ void SetSizeTestCase::SetSizeLessThanMinSize() CPPUNIT_ASSERT_EQUAL( size, m_win->GetSize() ); } +void SetSizeTestCase::BestSize() +{ + CPPUNIT_ASSERT_EQUAL( wxSize(50, 250), m_win->GetBestSize() ); + + m_win->SetMinSize(wxSize(100, 100)); + CPPUNIT_ASSERT_EQUAL( wxSize(100, 250), m_win->GetBestSize() ); + + m_win->SetMaxSize(wxSize(200, 200)); + CPPUNIT_ASSERT_EQUAL( wxSize(100, 200), m_win->GetBestSize() ); +}