]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/sizer.cpp
minimize searching for tlw parent, remove useless code
[wxWidgets.git] / src / common / sizer.cpp
index eb5eb59bbe954651f3b9bdcedef4d05b23978e5c..930aa061bbb11d047ca7479527eb05b24dcbb2f7 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "wx/display.h"
 #include "wx/sizer.h"
+#include "wx/private/flagscheck.h"
 
 #ifndef WX_PRECOMP
     #include "wx/string.h"
@@ -87,6 +88,31 @@ WX_DEFINE_EXPORTED_LIST( wxSizerItemList )
 // wxSizerItem
 // ----------------------------------------------------------------------------
 
+// check for flags conflicts
+static const int SIZER_FLAGS_MASK =
+    wxADD_FLAG(wxCENTRE,
+    wxADD_FLAG(wxHORIZONTAL,
+    wxADD_FLAG(wxVERTICAL,
+    wxADD_FLAG(wxLEFT,
+    wxADD_FLAG(wxRIGHT,
+    wxADD_FLAG(wxUP,
+    wxADD_FLAG(wxDOWN,
+    wxADD_FLAG(wxALIGN_NOT,
+    wxADD_FLAG(wxALIGN_CENTER_HORIZONTAL,
+    wxADD_FLAG(wxALIGN_RIGHT,
+    wxADD_FLAG(wxALIGN_BOTTOM,
+    wxADD_FLAG(wxALIGN_CENTER_VERTICAL,
+    wxADD_FLAG(wxFIXED_MINSIZE,
+    wxADD_FLAG(wxRESERVE_SPACE_EVEN_IF_HIDDEN,
+    wxADD_FLAG(wxSTRETCH_NOT,
+    wxADD_FLAG(wxSHRINK,
+    wxADD_FLAG(wxGROW,
+    wxADD_FLAG(wxSHAPED,
+    0))))))))))))))))));
+
+#define ASSERT_VALID_SIZER_FLAGS(f)  wxASSERT_VALID_FLAGS(f, SIZER_FLAGS_MASK)
+
+
 void wxSizerItem::Init(const wxSizerFlags& flags)
 {
     Init();
@@ -94,6 +120,8 @@ void wxSizerItem::Init(const wxSizerFlags& flags)
     m_proportion = flags.GetProportion();
     m_flag = flags.GetFlags();
     m_border = flags.GetBorderInPixels();
+
+    ASSERT_VALID_SIZER_FLAGS( m_flag );
 }
 
 wxSizerItem::wxSizerItem()
@@ -136,6 +164,8 @@ wxSizerItem::wxSizerItem(wxWindow *window,
              m_id(wxID_NONE),
              m_userData(userData)
 {
+    ASSERT_VALID_SIZER_FLAGS( m_flag );
+
     DoSetWindow(window);
 }
 
@@ -160,6 +190,8 @@ wxSizerItem::wxSizerItem(wxSizer *sizer,
              m_ratio(0.0),
              m_userData(userData)
 {
+    ASSERT_VALID_SIZER_FLAGS( m_flag );
+
     DoSetSizer(sizer);
 
     // m_minSize is set later
@@ -189,6 +221,8 @@ wxSizerItem::wxSizerItem(int width,
              m_id(wxID_NONE),
              m_userData(userData)
 {
+    ASSERT_VALID_SIZER_FLAGS( m_flag );
+
     DoSetSpacer(wxSize(width, height));
 }
 
@@ -522,6 +556,9 @@ void wxSizerItem::Show( bool show )
 
 bool wxSizerItem::IsShown() const
 {
+    if ( m_flag & wxRESERVE_SPACE_EVEN_IF_HIDDEN )
+        return true;
+
     switch ( m_kind )
     {
         case Item_None:
@@ -834,10 +871,13 @@ void wxSizer::DeleteWindows()
     }
 }
 
-wxSize wxSizer::Fit( wxWindow *window )
+wxSize wxSizer::ComputeFittingClientSize(wxWindow *window)
 {
+    wxCHECK_MSG( window, wxDefaultSize, "window can't be NULL" );
+
     // take the min size by default and limit it by max size
     wxSize size = GetMinClientSize(window);
+    wxSize sizeMax;
 
     wxTopLevelWindow *tlw = wxDynamicCast(window, wxTopLevelWindow);
     if ( tlw )
@@ -845,10 +885,9 @@ wxSize wxSizer::Fit( wxWindow *window )
         // hack for small screen devices where TLWs are always full screen
         if ( tlw->IsAlwaysMaximized() )
         {
-            // do nothing
-            return tlw->GetSize();
+            return tlw->GetClientSize();
         }
-        
+
         // limit the window to the size of the display it is on
         int disp = wxDisplay::GetFromWindow(window);
         if ( disp == wxNOT_FOUND )
@@ -857,40 +896,40 @@ wxSize wxSizer::Fit( wxWindow *window )
             disp = 0;
         }
 
-        wxSize sizeMax = wxDisplay(disp).GetClientArea().GetSize();
-        
+        sizeMax = wxDisplay(disp).GetClientArea().GetSize();
+
         // space for decorations and toolbars etc.
-        wxSize tlw_client_size = tlw->GetClientSize();
-        wxSize tlw_size = tlw->GetSize();
-        sizeMax.x -= tlw_size.x - tlw_client_size.x;
-        sizeMax.y -= tlw_size.y - tlw_client_size.y;
-        
-        if ( sizeMax.x != wxDefaultCoord && size.x > sizeMax.x )
-                size.x = sizeMax.x;
-        if ( sizeMax.y != wxDefaultCoord && size.y > sizeMax.y )
-                size.y = sizeMax.y;
-
-        // set client size
-        tlw->SetClientSize( size );
-        
-        // return entire size
-        return tlw->GetSize();
+        sizeMax = tlw->WindowToClientSize(sizeMax);
     }
     else
     {
-        wxSize sizeMax = GetMaxClientSize(window);
-        
-        if ( sizeMax.x != wxDefaultCoord && size.x > sizeMax.x )
-                size.x = sizeMax.x;
-        if ( sizeMax.y != wxDefaultCoord && size.y > sizeMax.y )
-                size.y = sizeMax.y;
+        sizeMax = GetMaxClientSize(window);
+    }
 
-        // set client size
-        window->SetClientSize( size );
+    if ( sizeMax.x != wxDefaultCoord && size.x > sizeMax.x )
+            size.x = sizeMax.x;
+    if ( sizeMax.y != wxDefaultCoord && size.y > sizeMax.y )
+            size.y = sizeMax.y;
 
-        // return entire size
-        return window->GetSize();
-    }
+    return size;
+}
+
+wxSize wxSizer::ComputeFittingWindowSize(wxWindow *window)
+{
+    wxCHECK_MSG( window, wxDefaultSize, "window can't be NULL" );
+
+    return window->ClientToWindowSize(ComputeFittingClientSize(window));
+}
+
+wxSize wxSizer::Fit( wxWindow *window )
+{
+    wxCHECK_MSG( window, wxDefaultSize, "window can't be NULL" );
+
+    // set client size
+    window->SetClientSize(ComputeFittingClientSize(window));
+
+    // return entire size
+    return window->GetSize();
 }
 
 void wxSizer::FitInside( wxWindow *window )
@@ -919,12 +958,16 @@ void wxSizer::SetSizeHints( wxWindow *window )
     // Preserve the window's max size hints, but set the
     // lower bound according to the sizer calculations.
 
-    wxSize size = Fit( window );
+    // This is equivalent to calling Fit(), except that we need to set
+    // the size hints _in between_ the two steps performed by Fit
+    // (1. ComputeFittingClientSize, 2. SetClientSize). That's because
+    // otherwise SetClientSize() could have no effect if there already are
+    // size hints in effect that forbid requested client size.
+
+    const wxSize clientSize = ComputeFittingClientSize(window);
 
-    window->SetSizeHints( size.x,
-                          size.y,
-                          window->GetMaxWidth(),
-                          window->GetMaxHeight() );
+    window->SetMinClientSize(clientSize);
+    window->SetClientSize(clientSize);
 }
 
 #if WXWIN_COMPATIBILITY_2_8
@@ -934,38 +977,12 @@ void wxSizer::SetVirtualSizeHints( wxWindow *window )
 }
 #endif // WXWIN_COMPATIBILITY_2_8
 
-wxSize wxSizer::GetMaxWindowSize( wxWindow *window ) const
-{
-    return window->GetMaxSize();
-}
-
-wxSize wxSizer::GetMinWindowSize( wxWindow *window )
-{
-    wxSize      minSize( GetMinSize() );
-    wxSize      size( window->GetSize() );
-    wxSize      client_size( window->GetClientSize() );
-
-    return wxSize( minSize.x+size.x-client_size.x,
-                   minSize.y+size.y-client_size.y );
-}
-
 // TODO on mac we need a function that determines how much free space this
 // min size contains, in order to make sure that we have 20 pixels of free
 // space around the controls
 wxSize wxSizer::GetMaxClientSize( wxWindow *window ) const
 {
-    wxSize maxSize( window->GetMaxSize() );
-
-    if ( maxSize != wxDefaultSize )
-    {
-        wxSize size( window->GetSize() );
-        wxSize client_size( window->GetClientSize() );
-
-        return wxSize( maxSize.x + client_size.x - size.x,
-                       maxSize.y + client_size.y - size.y );
-    }
-    else
-        return wxDefaultSize;
+    return window->WindowToClientSize(window->GetMaxSize());
 }
 
 wxSize wxSizer::GetMinClientSize( wxWindow *WXUNUSED(window) )