1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     provide new wxSizer class for layout 
   4 // Author:      Robert Roebling and Robin Dunn, contributions by 
   5 //              Dirk Holtwick, Ron Lee 
   6 // Modified by: Ron Lee 
   9 // Copyright:   (c) Robin Dunn, Robert Roebling 
  10 // Licence:     wxWindows licence 
  11 ///////////////////////////////////////////////////////////////////////////// 
  13 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  14 #pragma implementation "sizer.h" 
  17 // For compilers that support precompilation, includes "wx.h". 
  18 #include "wx/wxprec.h" 
  25     #include "wx/string.h" 
  31 #include "wx/statbox.h" 
  32 #include "wx/settings.h" 
  33 #include "wx/listimpl.cpp" 
  35 #if WXWIN_COMPATIBILITY_2_4 
  36     #include "wx/notebook.h" 
  39 //--------------------------------------------------------------------------- 
  41 IMPLEMENT_CLASS(wxSizerItem
, wxObject
) 
  42 IMPLEMENT_CLASS(wxSizer
, wxObject
) 
  43 IMPLEMENT_CLASS(wxGridSizer
, wxSizer
) 
  44 IMPLEMENT_CLASS(wxFlexGridSizer
, wxGridSizer
) 
  45 IMPLEMENT_CLASS(wxBoxSizer
, wxSizer
) 
  47 IMPLEMENT_CLASS(wxStaticBoxSizer
, wxBoxSizer
) 
  50 IMPLEMENT_CLASS(wxStdDialogButtonSizer
, wxBoxSizer
) 
  53 WX_DEFINE_EXPORTED_LIST( wxSizerItemList 
); 
  88 //--------------------------------------------------------------------------- 
  90 //--------------------------------------------------------------------------- 
  92 void wxSizerItem::Init() 
  98     m_zoneRect 
= wxRect(0,0,0,0); 
 101 void wxSizerItem::Init(const wxSizerFlags
& flags
) 
 105     m_proportion 
= flags
.GetProportion(); 
 106     m_flag 
= flags
.GetFlags(); 
 107     m_border 
= flags
.GetBorderInPixels(); 
 110 wxSizerItem::wxSizerItem( int width
, int height
, int proportion
, int flag
, int border
, wxObject
* userData 
) 
 113     , m_size( wxSize( width
, height 
) ) // size is set directly 
 114     , m_minSize( m_size 
)               // minimal size is the initial size 
 115     , m_proportion( proportion 
) 
 120     , m_userData( userData 
) 
 125 wxSizerItem::wxSizerItem( wxWindow 
*window
, int proportion
, int flag
, int border
, wxObject
* userData 
) 
 128     , m_proportion( proportion 
) 
 133     , m_userData( userData 
) 
 135     if (flag 
& wxFIXED_MINSIZE
) 
 136         window
->SetMinSize(window
->GetSize()); 
 137     m_minSize 
= window
->GetSize(); 
 139     // aspect ratio calculated from initial size 
 140     SetRatio( m_minSize 
); 
 142     // m_size is calculated later 
 145 wxSizerItem::wxSizerItem( wxSizer 
*sizer
, int proportion
, int flag
, int border
, wxObject
* userData 
) 
 148     , m_proportion( proportion 
) 
 154     , m_userData( userData 
) 
 156     // m_minSize is calculated later 
 157     // m_size is calculated later 
 160 wxSizerItem::wxSizerItem() 
 169 wxSizerItem::~wxSizerItem() 
 175         m_window
->SetContainingSizer(NULL
); 
 177     else // we must be a sizer 
 184 wxSize 
wxSizerItem::GetSize() const 
 188         ret 
= m_sizer
->GetSize(); 
 191         ret 
= m_window
->GetSize(); 
 198     if (m_flag 
& wxNORTH
) 
 200     if (m_flag 
& wxSOUTH
) 
 206 wxSize 
wxSizerItem::CalcMin() 
 210         m_minSize 
= m_sizer
->GetMinSize(); 
 212         // if we have to preserve aspect ratio _AND_ this is 
 213         // the first-time calculation, consider ret to be initial size 
 214         if ((m_flag 
& wxSHAPED
) && !m_ratio
) 
 217     else if ( IsWindow() ) 
 219         // Since the size of the window may change during runtime, we 
 220         // should use the current minimal/best size. 
 221         m_minSize 
= m_window
->GetBestFittingSize(); 
 224     return GetMinSizeWithBorder(); 
 227 wxSize 
wxSizerItem::GetMinSizeWithBorder() const 
 229     wxSize ret 
= m_minSize
; 
 235     if (m_flag 
& wxNORTH
) 
 237     if (m_flag 
& wxSOUTH
) 
 244 void wxSizerItem::SetDimension( wxPoint pos
, wxSize size 
) 
 246     if (m_flag 
& wxSHAPED
) 
 248         // adjust aspect ratio 
 249         int rwidth 
= (int) (size
.y 
* m_ratio
); 
 253             int rheight 
= (int) (size
.x 
/ m_ratio
); 
 254             // add vertical space 
 255             if (m_flag 
& wxALIGN_CENTER_VERTICAL
) 
 256                 pos
.y 
+= (size
.y 
- rheight
) / 2; 
 257             else if (m_flag 
& wxALIGN_BOTTOM
) 
 258                 pos
.y 
+= (size
.y 
- rheight
); 
 259             // use reduced dimensions 
 262         else if (rwidth 
< size
.x
) 
 264             // add horizontal space 
 265             if (m_flag 
& wxALIGN_CENTER_HORIZONTAL
) 
 266                 pos
.x 
+= (size
.x 
- rwidth
) / 2; 
 267             else if (m_flag 
& wxALIGN_RIGHT
) 
 268                 pos
.x 
+= (size
.x 
- rwidth
); 
 273     // This is what GetPosition() returns. Since we calculate 
 274     // borders afterwards, GetPosition() will be the left/top 
 275     // corner of the surrounding border. 
 287     if (m_flag 
& wxNORTH
) 
 292     if (m_flag 
& wxSOUTH
) 
 298         m_sizer
->SetDimension( pos
.x
, pos
.y
, size
.x
, size
.y 
); 
 300     m_zoneRect 
= wxRect(pos
, size
); 
 302         m_window
->SetSize( pos
.x
, pos
.y
, size
.x
, size
.y
, wxSIZE_ALLOW_MINUS_ONE 
); 
 307 void wxSizerItem::DeleteWindows() 
 316         m_sizer
->DeleteWindows(); 
 319 bool wxSizerItem::IsWindow() const 
 321     return (m_window 
!= NULL
); 
 324 bool wxSizerItem::IsSizer() const 
 326     return (m_sizer 
!= NULL
); 
 329 bool wxSizerItem::IsSpacer() const 
 331     return (m_window 
== NULL
) && (m_sizer 
== NULL
); 
 334 void wxSizerItem::Show( bool show 
) 
 339         m_window
->Show( show 
); 
 341         m_sizer
->ShowItems( show 
); 
 343     // ... nothing else to do to hide/show spacers 
 346 void wxSizerItem::SetOption( int option 
) 
 348     SetProportion( option 
); 
 351 int wxSizerItem::GetOption() const 
 353     return GetProportion(); 
 357 //--------------------------------------------------------------------------- 
 359 //--------------------------------------------------------------------------- 
 368     WX_CLEAR_LIST(wxSizerItemList
, m_children
); 
 371 wxSizerItem
* wxSizer::Insert( size_t index
, wxSizerItem 
*item 
) 
 373     m_children
.Insert( index
, item 
); 
 375     if( item
->GetWindow() ) 
 376         item
->GetWindow()->SetContainingSizer( this ); 
 381 bool wxSizer::Remove( wxWindow 
*window 
) 
 383     return Detach( window 
); 
 386 bool wxSizer::Remove( wxSizer 
*sizer 
) 
 388     wxASSERT_MSG( sizer
, _T("Removing NULL sizer") ); 
 390     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 393         wxSizerItem     
*item 
= node
->GetData(); 
 395         if (item
->GetSizer() == sizer
) 
 398             m_children
.Erase( node 
); 
 402         node 
= node
->GetNext(); 
 408 bool wxSizer::Remove( int index 
) 
 410     wxCHECK_MSG( index 
>= 0 && (size_t)index 
< m_children
.GetCount(), 
 412                  _T("Remove index is out of range") ); 
 414     wxSizerItemList::compatibility_iterator node 
= m_children
.Item( index 
); 
 416     wxCHECK_MSG( node
, false, _T("Failed to find child node") ); 
 418     wxSizerItem 
*item 
= node
->GetData(); 
 420     if( item
->IsWindow() ) 
 421         item
->GetWindow()->SetContainingSizer( NULL 
); 
 424     m_children
.Erase( node 
); 
 428 bool wxSizer::Detach( wxSizer 
*sizer 
) 
 430     wxASSERT_MSG( sizer
, _T("Detaching NULL sizer") ); 
 432     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 435         wxSizerItem     
*item 
= node
->GetData(); 
 437         if (item
->GetSizer() == sizer
) 
 441             m_children
.Erase( node 
); 
 444         node 
= node
->GetNext(); 
 450 bool wxSizer::Detach( wxWindow 
*window 
) 
 452     wxASSERT_MSG( window
, _T("Detaching NULL window") ); 
 454     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 457         wxSizerItem     
*item 
= node
->GetData(); 
 459         if (item
->GetWindow() == window
) 
 461             item
->GetWindow()->SetContainingSizer( NULL 
); 
 463             m_children
.Erase( node 
); 
 466         node 
= node
->GetNext(); 
 472 bool wxSizer::Detach( int index 
) 
 474     wxCHECK_MSG( index 
>= 0 && (size_t)index 
< m_children
.GetCount(), 
 476                  _T("Detach index is out of range") ); 
 478     wxSizerItemList::compatibility_iterator node 
= m_children
.Item( index 
); 
 480     wxCHECK_MSG( node
, false, _T("Failed to find child node") ); 
 482     wxSizerItem 
*item 
= node
->GetData(); 
 484     if( item
->IsSizer() ) 
 486     else if( item
->IsWindow() ) 
 487         item
->GetWindow()->SetContainingSizer( NULL 
); 
 490     m_children
.Erase( node 
); 
 494 void wxSizer::Clear( bool delete_windows 
) 
 496     // First clear the ContainingSizer pointers 
 497     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 500         wxSizerItem     
*item 
= node
->GetData(); 
 502         if (item
->IsWindow()) 
 503             item
->GetWindow()->SetContainingSizer( NULL 
); 
 504         node 
= node
->GetNext(); 
 507     // Destroy the windows if needed 
 511     // Now empty the list 
 512     WX_CLEAR_LIST(wxSizerItemList
, m_children
); 
 515 void wxSizer::DeleteWindows() 
 517     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 520         wxSizerItem     
*item 
= node
->GetData(); 
 522         item
->DeleteWindows(); 
 523         node 
= node
->GetNext(); 
 527 wxSize 
wxSizer::Fit( wxWindow 
*window 
) 
 529     wxSize 
size(window
->IsTopLevel() ? FitSize(window
) 
 530                                      : GetMinWindowSize(window
)); 
 532     window
->SetSize( size 
); 
 537 void wxSizer::FitInside( wxWindow 
*window 
) 
 540     if (window
->IsTopLevel()) 
 541         size 
= VirtualFitSize( window 
); 
 543         size 
= GetMinClientSize( window 
); 
 545     window
->SetVirtualSize( size 
); 
 548 void wxSizer::Layout() 
 550     // (re)calculates minimums needed for each item and other preparations 
 554     // Applies the layout and repositions/resizes the items 
 558 void wxSizer::SetSizeHints( wxWindow 
*window 
) 
 560     // Preserve the window's max size hints, but set the 
 561     // lower bound according to the sizer calculations. 
 563     wxSize size 
= Fit( window 
); 
 565     window
->SetSizeHints( size
.x
, 
 567                           window
->GetMaxWidth(), 
 568                           window
->GetMaxHeight() ); 
 571 void wxSizer::SetVirtualSizeHints( wxWindow 
*window 
) 
 573     // Preserve the window's max size hints, but set the 
 574     // lower bound according to the sizer calculations. 
 577     wxSize 
size( window
->GetVirtualSize() ); 
 578     window
->SetVirtualSizeHints( size
.x
, 
 580                                  window
->GetMaxWidth(), 
 581                                  window
->GetMaxHeight() ); 
 584 wxSize 
wxSizer::GetMaxWindowSize( wxWindow 
*window 
) const 
 586     return window
->GetMaxSize(); 
 589 wxSize 
wxSizer::GetMinWindowSize( wxWindow 
*window 
) 
 591     wxSize      
minSize( GetMinSize() ); 
 592     wxSize      
size( window
->GetSize() ); 
 593     wxSize      
client_size( window
->GetClientSize() ); 
 595     return wxSize( minSize
.x
+size
.x
-client_size
.x
, 
 596                    minSize
.y
+size
.y
-client_size
.y 
); 
 599 // TODO on mac we need a function that determines how much free space this 
 600 // min size contains, in order to make sure that we have 20 pixels of free 
 601 // space around the controls 
 603 // Return a window size that will fit within the screens dimensions 
 604 wxSize 
wxSizer::FitSize( wxWindow 
*window 
) 
 606     wxSize size     
= GetMinWindowSize( window 
); 
 607     wxSize sizeMax  
= GetMaxWindowSize( window 
); 
 609     // Limit the size if sizeMax != wxDefaultSize 
 611     if ( size
.x 
> sizeMax
.x 
&& sizeMax
.x 
!= wxDefaultCoord 
) 
 613     if ( size
.y 
> sizeMax
.y 
&& sizeMax
.y 
!= wxDefaultCoord 
) 
 619 wxSize 
wxSizer::GetMaxClientSize( wxWindow 
*window 
) const 
 621     wxSize 
maxSize( window
->GetMaxSize() ); 
 623     if( maxSize 
!= wxDefaultSize 
) 
 625         wxSize 
size( window
->GetSize() ); 
 626         wxSize 
client_size( window
->GetClientSize() ); 
 628         return wxSize( maxSize
.x 
+ client_size
.x 
- size
.x
, 
 629                        maxSize
.y 
+ client_size
.y 
- size
.y 
); 
 632         return wxDefaultSize
; 
 635 wxSize 
wxSizer::GetMinClientSize( wxWindow 
*WXUNUSED(window
) ) 
 637     return GetMinSize();  // Already returns client size. 
 640 wxSize 
wxSizer::VirtualFitSize( wxWindow 
*window 
) 
 642     wxSize size     
= GetMinClientSize( window 
); 
 643     wxSize sizeMax  
= GetMaxClientSize( window 
); 
 645     // Limit the size if sizeMax != wxDefaultSize 
 647     if ( size
.x 
> sizeMax
.x 
&& sizeMax
.x 
!= wxDefaultCoord 
) 
 649     if ( size
.y 
> sizeMax
.y 
&& sizeMax
.y 
!= wxDefaultCoord 
) 
 655 void wxSizer::SetDimension( int x
, int y
, int width
, int height 
) 
 664 wxSize 
wxSizer::GetMinSize() 
 666     wxSize 
ret( CalcMin() ); 
 667     if (ret
.x 
< m_minSize
.x
) ret
.x 
= m_minSize
.x
; 
 668     if (ret
.y 
< m_minSize
.y
) ret
.y 
= m_minSize
.y
; 
 672 void wxSizer::DoSetMinSize( int width
, int height 
) 
 675     m_minSize
.y 
= height
; 
 678 bool wxSizer::DoSetItemMinSize( wxWindow 
*window
, int width
, int height 
) 
 680     wxASSERT_MSG( window
, _T("SetMinSize for NULL window") ); 
 682     // Is it our immediate child? 
 684     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 687         wxSizerItem     
*item 
= node
->GetData(); 
 689         if (item
->GetWindow() == window
) 
 691             item
->SetMinSize( width
, height 
); 
 694         node 
= node
->GetNext(); 
 697     // No?  Search any subsizers we own then 
 699     node 
= m_children
.GetFirst(); 
 702         wxSizerItem     
*item 
= node
->GetData(); 
 704         if ( item
->GetSizer() && 
 705              item
->GetSizer()->DoSetItemMinSize( window
, width
, height 
) ) 
 707             // A child sizer found the requested windw, exit. 
 710         node 
= node
->GetNext(); 
 716 bool wxSizer::DoSetItemMinSize( wxSizer 
*sizer
, int width
, int height 
) 
 718     wxASSERT_MSG( sizer
, _T("SetMinSize for NULL sizer") ); 
 720     // Is it our immediate child? 
 722     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 725         wxSizerItem     
*item 
= node
->GetData(); 
 727         if (item
->GetSizer() == sizer
) 
 729             item
->GetSizer()->DoSetMinSize( width
, height 
); 
 732         node 
= node
->GetNext(); 
 735     // No?  Search any subsizers we own then 
 737     node 
= m_children
.GetFirst(); 
 740         wxSizerItem     
*item 
= node
->GetData(); 
 742         if ( item
->GetSizer() && 
 743              item
->GetSizer()->DoSetItemMinSize( sizer
, width
, height 
) ) 
 745             // A child found the requested sizer, exit. 
 748         node 
= node
->GetNext(); 
 754 bool wxSizer::DoSetItemMinSize( size_t index
, int width
, int height 
) 
 756     wxSizerItemList::compatibility_iterator node 
= m_children
.Item( index 
); 
 758     wxCHECK_MSG( node
, false, _T("Failed to find child node") ); 
 760     wxSizerItem     
*item 
= node
->GetData(); 
 762     if (item
->GetSizer()) 
 764         // Sizers contains the minimal size in them, if not calculated ... 
 765         item
->GetSizer()->DoSetMinSize( width
, height 
); 
 769         // ... but the minimal size of spacers and windows is stored via the item 
 770         item
->SetMinSize( width
, height 
); 
 776 wxSizerItem
* wxSizer::GetItem( wxWindow 
*window
, bool recursive 
) 
 778     wxASSERT_MSG( window
, _T("GetItem for NULL window") ); 
 780     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 783         wxSizerItem     
*item 
= node
->GetData(); 
 785         if (item
->GetWindow() == window
) 
 789         else if (recursive 
&& item
->IsSizer()) 
 791             wxSizerItem 
*subitem 
= item
->GetSizer()->GetItem( window
, true ); 
 796         node 
= node
->GetNext(); 
 802 wxSizerItem
* wxSizer::GetItem( wxSizer 
*sizer
, bool recursive 
) 
 804     wxASSERT_MSG( sizer
, _T("GetItem for NULL sizer") ); 
 806     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 809         wxSizerItem 
*item 
= node
->GetData(); 
 811         if (item
->GetSizer() == sizer
) 
 815         else if (recursive 
&& item
->IsSizer()) 
 817             wxSizerItem 
*subitem 
= item
->GetSizer()->GetItem( sizer
, true ); 
 822         node 
= node
->GetNext(); 
 828 wxSizerItem
* wxSizer::GetItem( size_t index 
) 
 830     wxCHECK_MSG( index 
< m_children
.GetCount(), 
 832                  _T("GetItem index is out of range") ); 
 834     return m_children
.Item( index 
)->GetData(); 
 837 bool wxSizer::Show( wxWindow 
*window
, bool show
, bool recursive 
) 
 839     wxSizerItem 
*item 
= GetItem( window
, recursive 
); 
 850 bool wxSizer::Show( wxSizer 
*sizer
, bool show
, bool recursive 
) 
 852     wxSizerItem 
*item 
= GetItem( sizer
, recursive 
); 
 863 bool wxSizer::Show( size_t index
, bool show
) 
 865     wxSizerItem 
*item 
= GetItem( index 
); 
 876 void wxSizer::ShowItems( bool show 
) 
 878     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 881         node
->GetData()->Show( show 
); 
 882         node 
= node
->GetNext(); 
 886 bool wxSizer::IsShown( wxWindow 
*window 
) const 
 888     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 891         wxSizerItem     
*item 
= node
->GetData(); 
 893         if (item
->GetWindow() == window
) 
 895             return item
->IsShown(); 
 897         node 
= node
->GetNext(); 
 900     wxFAIL_MSG( _T("IsShown failed to find sizer item") ); 
 905 bool wxSizer::IsShown( wxSizer 
*sizer 
) const 
 907     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 910         wxSizerItem     
*item 
= node
->GetData(); 
 912         if (item
->GetSizer() == sizer
) 
 914             return item
->IsShown(); 
 916         node 
= node
->GetNext(); 
 919     wxFAIL_MSG( _T("IsShown failed to find sizer item") ); 
 924 bool wxSizer::IsShown( size_t index 
) const 
 926     wxCHECK_MSG( index 
< m_children
.GetCount(), 
 928                  _T("IsShown index is out of range") ); 
 930     return m_children
.Item( index 
)->GetData()->IsShown(); 
 934 //--------------------------------------------------------------------------- 
 936 //--------------------------------------------------------------------------- 
 938 wxGridSizer::wxGridSizer( int rows
, int cols
, int vgap
, int hgap 
) 
 944     if (m_rows 
== 0 && m_cols 
== 0) 
 948 wxGridSizer::wxGridSizer( int cols
, int vgap
, int hgap 
) 
 954     if (m_rows 
== 0 && m_cols 
== 0) 
 958 int wxGridSizer::CalcRowsCols(int& nrows
, int& ncols
) const 
 960     int nitems 
= m_children
.GetCount(); 
 966             nrows 
= (nitems 
+ m_cols 
- 1) / m_cols
; 
 970             ncols 
= (nitems 
+ m_rows 
- 1) / m_rows
; 
 973         else // 0 columns, 0 rows? 
 975             wxFAIL_MSG( _T("grid sizer must have either rows or columns fixed") ); 
 984 void wxGridSizer::RecalcSizes() 
 986     int nitems
, nrows
, ncols
; 
 987     if ( (nitems 
= CalcRowsCols(nrows
, ncols
)) == 0 ) 
 990     wxSize 
sz( GetSize() ); 
 991     wxPoint 
pt( GetPosition() ); 
 993     int w 
= (sz
.x 
- (ncols 
- 1) * m_hgap
) / ncols
; 
 994     int h 
= (sz
.y 
- (nrows 
- 1) * m_vgap
) / nrows
; 
 997     for (int c 
= 0; c 
< ncols
; c
++) 
1000         for (int r 
= 0; r 
< nrows
; r
++) 
1002             int i 
= r 
* ncols 
+ c
; 
1005                 wxSizerItemList::compatibility_iterator node 
= m_children
.Item( i 
); 
1007                 wxASSERT_MSG( node
, _T("Failed to find SizerItemList node") ); 
1009                 SetItemBounds( node
->GetData(), x
, y
, w
, h
); 
1017 wxSize 
wxGridSizer::CalcMin() 
1020     if ( CalcRowsCols(nrows
, ncols
) == 0 ) 
1021         return wxSize(10, 10); 
1023     // Find the max width and height for any component 
1027     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
1030         wxSizerItem     
*item 
= node
->GetData(); 
1031         wxSize           
sz( item
->CalcMin() ); 
1033         w 
= wxMax( w
, sz
.x 
); 
1034         h 
= wxMax( h
, sz
.y 
); 
1036         node 
= node
->GetNext(); 
1039     return wxSize( ncols 
* w 
+ (ncols
-1) * m_hgap
, 
1040                    nrows 
* h 
+ (nrows
-1) * m_vgap 
); 
1043 void wxGridSizer::SetItemBounds( wxSizerItem 
*item
, int x
, int y
, int w
, int h 
) 
1046     wxSize 
sz( item
->GetMinSizeWithBorder() ); 
1047     int flag 
= item
->GetFlag(); 
1049     if ((flag 
& wxEXPAND
) || (flag 
& wxSHAPED
)) 
1055         if (flag 
& wxALIGN_CENTER_HORIZONTAL
) 
1057             pt
.x 
= x 
+ (w 
- sz
.x
) / 2; 
1059         else if (flag 
& wxALIGN_RIGHT
) 
1061             pt
.x 
= x 
+ (w 
- sz
.x
); 
1064         if (flag 
& wxALIGN_CENTER_VERTICAL
) 
1066             pt
.y 
= y 
+ (h 
- sz
.y
) / 2; 
1068         else if (flag 
& wxALIGN_BOTTOM
) 
1070             pt
.y 
= y 
+ (h 
- sz
.y
); 
1074     item
->SetDimension(pt
, sz
); 
1077 //--------------------------------------------------------------------------- 
1079 //--------------------------------------------------------------------------- 
1081 wxFlexGridSizer::wxFlexGridSizer( int rows
, int cols
, int vgap
, int hgap 
) 
1082                : wxGridSizer( rows
, cols
, vgap
, hgap 
), 
1083                  m_flexDirection(wxBOTH
), 
1084                  m_growMode(wxFLEX_GROWMODE_SPECIFIED
) 
1088 wxFlexGridSizer::wxFlexGridSizer( int cols
, int vgap
, int hgap 
) 
1089                : wxGridSizer( cols
, vgap
, hgap 
), 
1090                  m_flexDirection(wxBOTH
), 
1091                  m_growMode(wxFLEX_GROWMODE_SPECIFIED
) 
1095 wxFlexGridSizer::~wxFlexGridSizer() 
1099 void wxFlexGridSizer::RecalcSizes() 
1101     int nitems
, nrows
, ncols
; 
1102     if ( (nitems 
= CalcRowsCols(nrows
, ncols
)) == 0 ) 
1105     wxPoint 
pt( GetPosition() ); 
1106     wxSize 
sz( GetSize() ); 
1108     AdjustForGrowables(sz
, m_calculatedMinSize
, nrows
, ncols
); 
1110     sz 
= wxSize( pt
.x 
+ sz
.x
, pt
.y 
+ sz
.y 
); 
1113     for (int c 
= 0; c 
< ncols
; c
++) 
1116         for (int r 
= 0; r 
< nrows
; r
++) 
1118             int i 
= r 
* ncols 
+ c
; 
1121                 wxSizerItemList::compatibility_iterator node 
= m_children
.Item( i 
); 
1123                 wxASSERT_MSG( node
, _T("Failed to find node") ); 
1125                 int w 
= wxMax( 0, wxMin( m_colWidths
[c
], sz
.x 
- x 
) ); 
1126                 int h 
= wxMax( 0, wxMin( m_rowHeights
[r
], sz
.y 
- y 
) ); 
1128                 SetItemBounds( node
->GetData(), x
, y
, w
, h
); 
1130             if (m_rowHeights
[r
] != -1) 
1131                 y 
= y 
+ m_rowHeights
[r
] + m_vgap
; 
1133         if (m_colWidths
[c
] != -1) 
1134             x 
= x 
+ m_colWidths
[c
] + m_hgap
; 
1138 wxSize 
wxFlexGridSizer::CalcMin() 
1144     // Number of rows/columns can change as items are added or removed. 
1145     if ( !CalcRowsCols(nrows
, ncols
) ) 
1146         return wxSize(10, 10); 
1148     m_rowHeights
.SetCount(nrows
); 
1149     m_colWidths
.SetCount(ncols
); 
1151     // We have to recalcuate the sizes in case the item minimum size has 
1152     // changed since the previous layout, or the item has been hidden using 
1153     // wxSizer::Show(). If all the items in a row/column are hidden, the final 
1154     // dimension of the row/column will be -1, indicating that the column 
1155     // itself is hidden. 
1156     for( s 
= m_rowHeights
.GetCount(), i 
= 0; i 
< s
; ++i 
) 
1157         m_rowHeights
[ i 
] = -1; 
1158     for( s 
= m_colWidths
.GetCount(), i 
= 0; i 
< s
; ++i 
) 
1159         m_colWidths
[ i 
] = -1; 
1161     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
1166         wxSizerItem    
*item 
= node
->GetData(); 
1167         if ( item
->IsShown() ) 
1169             wxSize 
sz( item
->CalcMin() ); 
1170             int row 
= i 
/ ncols
; 
1171             int col 
= i 
% ncols
; 
1173             m_rowHeights
[ row 
] = wxMax( wxMax( 0, sz
.y 
), m_rowHeights
[ row 
] ); 
1174             m_colWidths
[ col 
] = wxMax( wxMax( 0, sz
.x 
), m_colWidths
[ col 
] ); 
1177         node 
= node
->GetNext(); 
1181     AdjustForFlexDirection(); 
1183     // Sum total minimum size, including gaps between rows/columns. 
1184     // -1 is used as a magic number meaning empty column. 
1186     for (int col 
= 0; col 
< ncols
; col
++) 
1187         if ( m_colWidths
[ col 
] != -1 ) 
1188             width 
+= m_colWidths
[ col 
] + m_hgap
; 
1193     for (int row 
= 0; row 
< nrows
; row
++) 
1194         if ( m_rowHeights
[ row 
] != -1 ) 
1195             height 
+= m_rowHeights
[ row 
] + m_vgap
; 
1199     m_calculatedMinSize 
= wxSize( width
, height 
); 
1200     return m_calculatedMinSize
; 
1203 void wxFlexGridSizer::AdjustForFlexDirection() 
1205     // the logic in CalcMin works when we resize flexibly in both directions 
1206     // but maybe this is not the case 
1207     if ( m_flexDirection 
!= wxBOTH 
) 
1209         // select the array corresponding to the direction in which we do *not* 
1211         wxArrayInt
& array 
= m_flexDirection 
== wxVERTICAL 
? m_colWidths
 
1214         const int count 
= array
.GetCount(); 
1216         // find the largest value in this array 
1218         for ( n 
= 0; n 
< count
; ++n 
) 
1220             if ( array
[n
] > largest 
) 
1224         // and now fill it with the largest value 
1225         for ( n 
= 0; n 
< count
; ++n 
) 
1233 void wxFlexGridSizer::AdjustForGrowables(const wxSize
& sz
, const wxSize
& minsz
, 
1234                                          int nrows
, int ncols
) 
1236     // what to do with the rows? by default, resize them proportionally 
1237     if ( sz
.y 
> minsz
.y 
&& ( (m_flexDirection 
& wxVERTICAL
) || (m_growMode 
== wxFLEX_GROWMODE_SPECIFIED
) ) ) 
1239         int sum_proportions 
= 0; 
1240         int growable_space 
= 0; 
1243         for (idx 
= 0; idx 
< m_growableRows
.GetCount(); idx
++) 
1245             // Since the number of rows/columns can change as items are 
1246             // inserted/deleted, we need to verify at runtime that the 
1247             // requested growable rows/columns are still valid. 
1248             if (m_growableRows
[idx
] >= nrows
) 
1251             // If all items in a row/column are hidden, that row/column will 
1252             // have a dimension of -1.  This causes the row/column to be 
1253             // hidden completely. 
1254             if (m_rowHeights
[ m_growableRows
[idx
] ] == -1) 
1256             sum_proportions 
+= m_growableRowsProportions
[idx
]; 
1257             growable_space 
+= m_rowHeights
[ m_growableRows
[idx
] ]; 
1263             for (idx 
= 0; idx 
< m_growableRows
.GetCount(); idx
++) 
1265                 if (m_growableRows
[idx
] >= nrows 
) 
1267                 if (m_rowHeights
[ m_growableRows
[idx
] ] == -1) 
1268                     m_rowHeights
[ m_growableRows
[idx
] ] = 0; 
1271                     int delta 
= (sz
.y 
- minsz
.y
); 
1272                     if (sum_proportions 
== 0) 
1273                         delta 
= (delta
/num
) + m_rowHeights
[ m_growableRows
[idx
] ]; 
1275                         delta 
= ((delta
+growable_space
)*m_growableRowsProportions
[idx
]) / sum_proportions
; 
1276                     m_rowHeights
[ m_growableRows
[idx
] ] = delta
; 
1281     else if ( (m_growMode 
== wxFLEX_GROWMODE_ALL
) && (sz
.y 
> minsz
.y
) ) 
1283         // rounding problem? 
1284         for ( int row 
= 0; row 
< nrows
; ++row 
) 
1285             m_rowHeights
[ row 
] = sz
.y 
/ nrows
; 
1288     // the same logic as above but for the columns 
1289     if ( sz
.x 
> minsz
.x 
&& ( (m_flexDirection 
& wxHORIZONTAL
) || (m_growMode 
== wxFLEX_GROWMODE_SPECIFIED
) ) ) 
1291         int sum_proportions 
= 0; 
1292         int growable_space 
= 0; 
1295         for (idx 
= 0; idx 
< m_growableCols
.GetCount(); idx
++) 
1297             // Since the number of rows/columns can change as items are 
1298             // inserted/deleted, we need to verify at runtime that the 
1299             // requested growable rows/columns are still valid. 
1300             if (m_growableCols
[idx
] >= ncols
) 
1303             // If all items in a row/column are hidden, that row/column will 
1304             // have a dimension of -1.  This causes the column to be hidden 
1306             if (m_colWidths
[ m_growableCols
[idx
] ] == -1) 
1308             sum_proportions 
+= m_growableColsProportions
[idx
]; 
1309             growable_space 
+= m_colWidths
[ m_growableCols
[idx
] ]; 
1315             for (idx 
= 0; idx 
< m_growableCols
.GetCount(); idx
++) 
1317                 if (m_growableCols
[idx
] >= ncols 
) 
1319                 if (m_colWidths
[ m_growableCols
[idx
] ] == -1) 
1320                     m_colWidths
[ m_growableCols
[idx
] ] = 0; 
1323                     int delta 
= (sz
.x 
- minsz
.x
); 
1324                     if (sum_proportions 
== 0) 
1325                         delta 
= (delta
/num
) + m_colWidths
[ m_growableCols
[idx
] ]; 
1327                         delta 
= ((delta
+growable_space
)*m_growableColsProportions
[idx
])/sum_proportions
; 
1328                     m_colWidths
[ m_growableCols
[idx
] ] = delta
; 
1333     else if ( (m_growMode 
== wxFLEX_GROWMODE_ALL
) && (sz
.x 
> minsz
.x
) ) 
1335         for ( int col
=0; col 
< ncols
; ++col 
) 
1336             m_colWidths
[ col 
] = sz
.x 
/ ncols
; 
1341 void wxFlexGridSizer::AddGrowableRow( size_t idx
, int proportion 
) 
1343     m_growableRows
.Add( idx 
); 
1344     m_growableRowsProportions
.Add( proportion 
); 
1347 void wxFlexGridSizer::RemoveGrowableRow( size_t idx 
) 
1349     m_growableRows
.Remove( idx 
); 
1352 void wxFlexGridSizer::AddGrowableCol( size_t idx
, int proportion 
) 
1354     m_growableCols
.Add( idx 
); 
1355     m_growableColsProportions
.Add( proportion 
); 
1358 void wxFlexGridSizer::RemoveGrowableCol( size_t idx 
) 
1360     m_growableCols
.Remove( idx 
); 
1363 //--------------------------------------------------------------------------- 
1365 //--------------------------------------------------------------------------- 
1367 wxBoxSizer::wxBoxSizer( int orient 
) 
1368     : m_orient( orient 
) 
1372 void wxBoxSizer::RecalcSizes() 
1374     if (m_children
.GetCount() == 0) 
1380         if (m_orient 
== wxHORIZONTAL
) 
1381             delta 
= m_size
.x 
- m_fixedWidth
; 
1383             delta 
= m_size
.y 
- m_fixedHeight
; 
1386     wxPoint 
pt( m_position 
); 
1388     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
1391         wxSizerItem     
*item 
= node
->GetData(); 
1393         if (item
->IsShown()) 
1395             wxSize 
size( item
->GetMinSizeWithBorder() ); 
1397             if (m_orient 
== wxVERTICAL
) 
1399                 wxCoord height 
= size
.y
; 
1400                 if (item
->GetProportion()) 
1402                     // Because of at least one visible item has non-zero 
1403                     // proportion then m_stretchable is not zero 
1404                     height 
= (delta 
* item
->GetProportion()) / m_stretchable
; 
1407                 wxPoint 
child_pos( pt 
); 
1408                 wxSize  
child_size( size
.x
, height 
); 
1410                 if (item
->GetFlag() & (wxEXPAND 
| wxSHAPED
)) 
1411                     child_size
.x 
= m_size
.x
; 
1412                 else if (item
->GetFlag() & wxALIGN_RIGHT
) 
1413                     child_pos
.x 
+= m_size
.x 
- size
.x
; 
1414                 else if (item
->GetFlag() & (wxCENTER 
| wxALIGN_CENTER_HORIZONTAL
)) 
1415                 // XXX wxCENTER is added for backward compatibility; 
1416                 //     wxALIGN_CENTER should be used in new code 
1417                     child_pos
.x 
+= (m_size
.x 
- size
.x
) / 2; 
1419                 item
->SetDimension( child_pos
, child_size 
); 
1425                 wxCoord width 
= size
.x
; 
1426                 if (item
->GetProportion()) 
1428                     // Because of at least one visible item has non-zero 
1429                     // proportion then m_stretchable is not zero 
1430                     width 
= (delta 
* item
->GetProportion()) / m_stretchable
; 
1433                 wxPoint 
child_pos( pt 
); 
1434                 wxSize  
child_size( width
, size
.y 
); 
1436                 if (item
->GetFlag() & (wxEXPAND 
| wxSHAPED
)) 
1437                     child_size
.y 
= m_size
.y
; 
1438                 else if (item
->GetFlag() & wxALIGN_BOTTOM
) 
1439                     child_pos
.y 
+= m_size
.y 
- size
.y
; 
1440                 else if (item
->GetFlag() & (wxCENTER 
| wxALIGN_CENTER_VERTICAL
)) 
1441                 // XXX wxCENTER is added for backward compatibility; 
1442                 //     wxALIGN_CENTER should be used in new code 
1443                     child_pos
.y 
+= (m_size
.y 
- size
.y
) / 2; 
1445                 item
->SetDimension( child_pos
, child_size 
); 
1451         node 
= node
->GetNext(); 
1455 wxSize 
wxBoxSizer::CalcMin() 
1457     if (m_children
.GetCount() == 0) 
1458         return wxSize(10,10); 
1466     // precalc item minsizes and count proportions 
1467     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
1470         wxSizerItem 
*item 
= node
->GetData(); 
1472         if (item
->IsShown()) 
1473             item
->CalcMin();  // result is stored in the item 
1475         if (item
->IsShown() && item
->GetProportion() != 0) 
1476             m_stretchable 
+= item
->GetProportion(); 
1478         node 
= node
->GetNext(); 
1481     // Total minimum size (width or height) of sizer 
1484     node 
= m_children
.GetFirst(); 
1487         wxSizerItem 
*item 
= node
->GetData(); 
1489         if (item
->IsShown() && item
->GetProportion() != 0) 
1491             int stretch 
= item
->GetProportion(); 
1492             wxSize 
size( item
->GetMinSizeWithBorder() ); 
1495             // Integer division rounded up is (a + b - 1) / b 
1496             // Round up needed in order to guarantee that all 
1497             // all items will have size not less then their min size 
1498             if (m_orient 
== wxHORIZONTAL
) 
1499                 minSize 
= ( size
.x
*m_stretchable 
+ stretch 
- 1)/stretch
; 
1501                 minSize 
= ( size
.y
*m_stretchable 
+ stretch 
- 1)/stretch
; 
1503             if (minSize 
> maxMinSize
) 
1504                 maxMinSize 
= minSize
; 
1506         node 
= node
->GetNext(); 
1509     // Calculate overall minimum size 
1510     node 
= m_children
.GetFirst(); 
1513         wxSizerItem 
*item 
= node
->GetData(); 
1515         if (item
->IsShown()) 
1517             wxSize 
size( item
->GetMinSizeWithBorder() ); 
1518             if (item
->GetProportion() != 0) 
1520                 if (m_orient 
== wxHORIZONTAL
) 
1521                     size
.x 
= (maxMinSize
*item
->GetProportion())/m_stretchable
; 
1523                     size
.y 
= (maxMinSize
*item
->GetProportion())/m_stretchable
; 
1527                 if (m_orient 
== wxVERTICAL
) 
1529                     m_fixedHeight 
+= size
.y
; 
1530                     m_fixedWidth 
= wxMax( m_fixedWidth
, size
.x 
); 
1534                     m_fixedWidth 
+= size
.x
; 
1535                     m_fixedHeight 
= wxMax( m_fixedHeight
, size
.y 
); 
1539             if (m_orient 
== wxHORIZONTAL
) 
1541                 m_minWidth 
+= size
.x
; 
1542                 m_minHeight 
= wxMax( m_minHeight
, size
.y 
); 
1546                 m_minHeight 
+= size
.y
; 
1547                 m_minWidth 
= wxMax( m_minWidth
, size
.x 
); 
1550         node 
= node
->GetNext(); 
1553     return wxSize( m_minWidth
, m_minHeight 
); 
1556 //--------------------------------------------------------------------------- 
1558 //--------------------------------------------------------------------------- 
1562 wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox 
*box
, int orient 
) 
1563     : wxBoxSizer( orient 
) 
1564     , m_staticBox( box 
) 
1566     wxASSERT_MSG( box
, wxT("wxStaticBoxSizer needs a static box") ); 
1569 wxStaticBoxSizer::wxStaticBoxSizer(int orient
, wxWindow 
*win
, const wxString
& s
) 
1570                 : wxBoxSizer(orient
), 
1571                   m_staticBox(new wxStaticBox(win
, wxID_ANY
, s
)) 
1575 static void GetStaticBoxBorders( wxStaticBox 
*box
, 
1579     // this has to be done platform by platform as there is no way to 
1580     // guess the thickness of a wxStaticBox border 
1581     box
->GetBordersForSizer(borderTop
, borderOther
); 
1584 void wxStaticBoxSizer::RecalcSizes() 
1586     int top_border
, other_border
; 
1587     GetStaticBoxBorders(m_staticBox
, &top_border
, &other_border
); 
1589     m_staticBox
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y 
); 
1591     wxPoint 
old_pos( m_position 
); 
1592     m_position
.x 
+= other_border
; 
1593     m_position
.y 
+= top_border
; 
1594     wxSize 
old_size( m_size 
); 
1595     m_size
.x 
-= 2*other_border
; 
1596     m_size
.y 
-= top_border 
+ other_border
; 
1598     wxBoxSizer::RecalcSizes(); 
1600     m_position 
= old_pos
; 
1604 wxSize 
wxStaticBoxSizer::CalcMin() 
1606     int top_border
, other_border
; 
1607     GetStaticBoxBorders(m_staticBox
, &top_border
, &other_border
); 
1609     wxSize 
ret( wxBoxSizer::CalcMin() ); 
1610     ret
.x 
+= 2*other_border
; 
1611     ret
.y 
+= other_border 
+ top_border
; 
1616 void wxStaticBoxSizer::ShowItems( bool show 
) 
1618     m_staticBox
->Show( show 
); 
1619     wxBoxSizer::ShowItems( show 
); 
1622 #endif // wxUSE_STATBOX 
1626 wxStdDialogButtonSizer::wxStdDialogButtonSizer() 
1627     : wxBoxSizer(wxHORIZONTAL
) 
1629     // Vertical buttons with lots of space on either side 
1630     // looks rubbish on WinCE, so let's not do this for now. 
1631     // If we are going to use vertical buttons, we should 
1632     // put the sizer to the right of other controls in the dialog, 
1633     // and that's beyond the scope of this sizer. 
1635     bool is_pda 
= (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
); 
1636     // If we have a PDA screen, put yes/no button over 
1637     // all other buttons, otherwise on the left side. 
1639         m_orient 
= wxVERTICAL
; 
1642     m_buttonAffirmative 
= NULL
; 
1643     m_buttonApply 
= NULL
; 
1644     m_buttonNegative 
= NULL
; 
1645     m_buttonCancel 
= NULL
; 
1646     m_buttonHelp 
= NULL
; 
1649 void wxStdDialogButtonSizer::AddButton(wxButton 
*mybutton
) 
1651     switch (mybutton
->GetId()) 
1656             m_buttonAffirmative 
= mybutton
; 
1659             m_buttonApply 
= mybutton
; 
1662             m_buttonNegative 
= mybutton
; 
1665             m_buttonCancel 
= mybutton
; 
1668         case wxID_CONTEXT_HELP
: 
1669             m_buttonHelp 
= mybutton
; 
1676 void wxStdDialogButtonSizer::SetAffirmativeButton( wxButton 
*button 
) 
1678     m_buttonAffirmative 
= button
; 
1681 void wxStdDialogButtonSizer::SetNegativeButton( wxButton 
*button 
) 
1683     m_buttonNegative 
= button
; 
1686 void wxStdDialogButtonSizer::SetCancelButton( wxButton 
*button 
) 
1688     m_buttonCancel 
= button
; 
1691 void wxStdDialogButtonSizer::Realize() 
1694         Add(0, 0, 0, wxLEFT
, 6); 
1696             Add((wxWindow
*)m_buttonHelp
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 6); 
1698         if (m_buttonNegative
){ 
1699             // HIG POLICE BULLETIN - destructive buttons need extra padding 
1700             // 24 pixels on either side 
1701             Add((wxWindow
*)m_buttonNegative
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 12); 
1704         // extra whitespace between help/negative and cancel/ok buttons 
1705         Add(0, 0, 1, wxEXPAND
, 0); 
1707         if (m_buttonCancel
){ 
1708             Add((wxWindow
*)m_buttonCancel
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 6); 
1709             // Cancel or help should be default 
1710             // m_buttonCancel->SetDefaultButton(); 
1713         // Ugh, Mac doesn't really have apply dialogs, so I'll just 
1714         // figure the best place is between Cancel and OK 
1716             Add((wxWindow
*)m_buttonApply
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 6); 
1718         if (m_buttonAffirmative
){ 
1719             Add((wxWindow
*)m_buttonAffirmative
, 0, wxALIGN_CENTRE 
| wxLEFT
, 6); 
1721             if (m_buttonAffirmative
->GetId() == wxID_SAVE
){ 
1722                 // these buttons have set labels under Mac so we should use them 
1723                 m_buttonAffirmative
->SetLabel(_("Save")); 
1724                 m_buttonNegative
->SetLabel(_("Don't Save")); 
1728         // Extra space around and at the right 
1730 #elif defined(__WXGTK20__) 
1731         Add(0, 0, 0, wxLEFT
, 9); 
1733             Add((wxWindow
*)m_buttonHelp
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 3); 
1735         // extra whitespace between help and cancel/ok buttons 
1736         Add(0, 0, 1, wxEXPAND
, 0); 
1738         if (m_buttonNegative
){ 
1739             Add((wxWindow
*)m_buttonNegative
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 3); 
1742         if (m_buttonCancel
){ 
1743             Add((wxWindow
*)m_buttonCancel
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 3); 
1744             // Cancel or help should be default 
1745             // m_buttonCancel->SetDefaultButton(); 
1749             Add((wxWindow
*)m_buttonApply
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 3); 
1751         if (m_buttonAffirmative
) 
1752             Add((wxWindow
*)m_buttonAffirmative
, 0, wxALIGN_CENTRE 
| wxLEFT
, 6); 
1754     // do the same thing for GTK1 and Windows platforms 
1755     // and assume any platform not accounted for here will use 
1757         Add(0, 0, 0, wxLEFT
, 9); 
1759             Add((wxWindow
*)m_buttonHelp
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, m_buttonHelp
->ConvertDialogToPixels(wxSize(4, 0)).x
); 
1761         // extra whitespace between help and cancel/ok buttons 
1762         Add(0, 0, 1, wxEXPAND
, 0); 
1765             Add((wxWindow
*)m_buttonApply
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, m_buttonApply
->ConvertDialogToPixels(wxSize(4, 0)).x
); 
1767         if (m_buttonAffirmative
){ 
1768             Add((wxWindow
*)m_buttonAffirmative
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, m_buttonAffirmative
->ConvertDialogToPixels(wxSize(4, 0)).x
); 
1771         if (m_buttonNegative
){ 
1772             Add((wxWindow
*)m_buttonNegative
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, m_buttonNegative
->ConvertDialogToPixels(wxSize(4, 0)).x
); 
1775         if (m_buttonCancel
){ 
1776             Add((wxWindow
*)m_buttonCancel
, 0, wxALIGN_CENTRE 
| wxLEFT
, m_buttonCancel
->ConvertDialogToPixels(wxSize(4, 0)).x
); 
1777             // Cancel or help should be default 
1778             // m_buttonCancel->SetDefaultButton(); 
1784 #endif // wxUSE_BUTTON 
1786 #if WXWIN_COMPATIBILITY_2_4 
1788 // ---------------------------------------------------------------------------- 
1790 // ---------------------------------------------------------------------------- 
1793 IMPLEMENT_CLASS(wxBookCtrlSizer
, wxSizer
) 
1795 IMPLEMENT_CLASS(wxNotebookSizer
, wxBookCtrlSizer
) 
1796 #endif // wxUSE_NOTEBOOK 
1797 #endif // wxUSE_BOOKCTRL 
1801 wxBookCtrlSizer::wxBookCtrlSizer(wxBookCtrlBase 
*bookctrl
) 
1802                : m_bookctrl(bookctrl
) 
1804     wxASSERT_MSG( bookctrl
, wxT("wxBookCtrlSizer needs a control") ); 
1807 void wxBookCtrlSizer::RecalcSizes() 
1809     m_bookctrl
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y 
); 
1812 wxSize 
wxBookCtrlSizer::CalcMin() 
1814     wxSize sizeBorder 
= m_bookctrl
->CalcSizeFromPage(wxSize(0,0)); 
1819     if ( m_bookctrl
->GetPageCount() == 0 ) 
1821         return wxSize(sizeBorder
.x 
+ 10, sizeBorder
.y 
+ 10); 
1827     wxWindowList::compatibility_iterator
 
1828         node 
= m_bookctrl
->GetChildren().GetFirst(); 
1831         wxWindow 
*item 
= node
->GetData(); 
1832         wxSizer 
*itemsizer 
= item
->GetSizer(); 
1836             wxSize 
subsize( itemsizer
->CalcMin() ); 
1838             if (subsize
.x 
> maxX
) 
1840             if (subsize
.y 
> maxY
) 
1844         node 
= node
->GetNext(); 
1847     return wxSize( maxX
, maxY 
) + sizeBorder
; 
1852 wxNotebookSizer::wxNotebookSizer(wxNotebook 
*nb
) 
1854     wxASSERT_MSG( nb
, wxT("wxNotebookSizer needs a control") ); 
1858 #endif // wxUSE_NOTEBOOOK 
1859 #endif // wxUSE_BOOKCTRL 
1861 #endif // WXWIN_COMPATIBILITY_2_4