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" 
  40 #   include "wx/mac/uma.h" 
  43 //--------------------------------------------------------------------------- 
  45 IMPLEMENT_CLASS(wxSizerItem
, wxObject
) 
  46 IMPLEMENT_CLASS(wxSizer
, wxObject
) 
  47 IMPLEMENT_CLASS(wxGridSizer
, wxSizer
) 
  48 IMPLEMENT_CLASS(wxFlexGridSizer
, wxGridSizer
) 
  49 IMPLEMENT_CLASS(wxBoxSizer
, wxSizer
) 
  51 IMPLEMENT_CLASS(wxStaticBoxSizer
, wxBoxSizer
) 
  54 IMPLEMENT_CLASS(wxStdDialogButtonSizer
, wxBoxSizer
) 
  57 WX_DEFINE_EXPORTED_LIST( wxSizerItemList 
); 
  92 //--------------------------------------------------------------------------- 
  94 //--------------------------------------------------------------------------- 
  96 void wxSizerItem::Init() 
 102     m_zoneRect 
= wxRect(0,0,0,0); 
 105 void wxSizerItem::Init(const wxSizerFlags
& flags
) 
 109     m_proportion 
= flags
.GetProportion(); 
 110     m_flag 
= flags
.GetFlags(); 
 111     m_border 
= flags
.GetBorderInPixels(); 
 114 wxSizerItem::wxSizerItem( int width
, int height
, int proportion
, int flag
, int border
, wxObject
* userData 
) 
 117     , m_size( wxSize( width
, height 
) ) // size is set directly 
 118     , m_minSize( m_size 
)               // minimal size is the initial size 
 119     , m_proportion( proportion 
) 
 124     , m_userData( userData 
) 
 129 wxSizerItem::wxSizerItem( wxWindow 
*window
, int proportion
, int flag
, int border
, wxObject
* userData 
) 
 132     , m_proportion( proportion 
) 
 137     , m_userData( userData 
) 
 139     if (flag 
& wxFIXED_MINSIZE
) 
 140         window
->SetMinSize(window
->GetSize()); 
 141     m_minSize 
= window
->GetSize(); 
 143     // aspect ratio calculated from initial size 
 144     SetRatio( m_minSize 
); 
 146     // m_size is calculated later 
 149 wxSizerItem::wxSizerItem( wxSizer 
*sizer
, int proportion
, int flag
, int border
, wxObject
* userData 
) 
 152     , m_proportion( proportion 
) 
 158     , m_userData( userData 
) 
 160     // m_minSize is calculated later 
 161     // m_size is calculated later 
 164 wxSizerItem::wxSizerItem() 
 173 wxSizerItem::~wxSizerItem() 
 179         m_window
->SetContainingSizer(NULL
); 
 181     else // we must be a sizer 
 188 wxSize 
wxSizerItem::GetSize() const 
 192         ret 
= m_sizer
->GetSize(); 
 195         ret 
= m_window
->GetSize(); 
 202     if (m_flag 
& wxNORTH
) 
 204     if (m_flag 
& wxSOUTH
) 
 210 wxSize 
wxSizerItem::CalcMin() 
 214         m_minSize 
= m_sizer
->GetMinSize(); 
 216         // if we have to preserve aspect ratio _AND_ this is 
 217         // the first-time calculation, consider ret to be initial size 
 218         if ((m_flag 
& wxSHAPED
) && !m_ratio
) 
 221     else if ( IsWindow() ) 
 223         // Since the size of the window may change during runtime, we 
 224         // should use the current minimal/best size. 
 225         m_minSize 
= m_window
->GetBestFittingSize(); 
 228     return GetMinSizeWithBorder(); 
 231 wxSize 
wxSizerItem::GetMinSizeWithBorder() const 
 233     wxSize ret 
= m_minSize
; 
 239     if (m_flag 
& wxNORTH
) 
 241     if (m_flag 
& wxSOUTH
) 
 248 void wxSizerItem::SetDimension( wxPoint pos
, wxSize size 
) 
 250     if (m_flag 
& wxSHAPED
) 
 252         // adjust aspect ratio 
 253         int rwidth 
= (int) (size
.y 
* m_ratio
); 
 257             int rheight 
= (int) (size
.x 
/ m_ratio
); 
 258             // add vertical space 
 259             if (m_flag 
& wxALIGN_CENTER_VERTICAL
) 
 260                 pos
.y 
+= (size
.y 
- rheight
) / 2; 
 261             else if (m_flag 
& wxALIGN_BOTTOM
) 
 262                 pos
.y 
+= (size
.y 
- rheight
); 
 263             // use reduced dimensions 
 266         else if (rwidth 
< size
.x
) 
 268             // add horizontal space 
 269             if (m_flag 
& wxALIGN_CENTER_HORIZONTAL
) 
 270                 pos
.x 
+= (size
.x 
- rwidth
) / 2; 
 271             else if (m_flag 
& wxALIGN_RIGHT
) 
 272                 pos
.x 
+= (size
.x 
- rwidth
); 
 277     // This is what GetPosition() returns. Since we calculate 
 278     // borders afterwards, GetPosition() will be the left/top 
 279     // corner of the surrounding border. 
 291     if (m_flag 
& wxNORTH
) 
 296     if (m_flag 
& wxSOUTH
) 
 302         m_sizer
->SetDimension( pos
.x
, pos
.y
, size
.x
, size
.y 
); 
 304     m_zoneRect 
= wxRect(pos
, size
); 
 306         m_window
->SetSize( pos
.x
, pos
.y
, size
.x
, size
.y
, wxSIZE_ALLOW_MINUS_ONE 
); 
 311 void wxSizerItem::DeleteWindows() 
 320         m_sizer
->DeleteWindows(); 
 323 bool wxSizerItem::IsWindow() const 
 325     return (m_window 
!= NULL
); 
 328 bool wxSizerItem::IsSizer() const 
 330     return (m_sizer 
!= NULL
); 
 333 bool wxSizerItem::IsSpacer() const 
 335     return (m_window 
== NULL
) && (m_sizer 
== NULL
); 
 338 void wxSizerItem::Show( bool show 
) 
 343         m_window
->Show( show 
); 
 345         m_sizer
->ShowItems( show 
); 
 347     // ... nothing else to do to hide/show spacers 
 350 void wxSizerItem::SetOption( int option 
) 
 352     SetProportion( option 
); 
 355 int wxSizerItem::GetOption() const 
 357     return GetProportion(); 
 361 //--------------------------------------------------------------------------- 
 363 //--------------------------------------------------------------------------- 
 372     WX_CLEAR_LIST(wxSizerItemList
, m_children
); 
 375 wxSizerItem
* wxSizer::Insert( size_t index
, wxSizerItem 
*item 
) 
 377     m_children
.Insert( index
, item 
); 
 379     if( item
->GetWindow() ) 
 380         item
->GetWindow()->SetContainingSizer( this ); 
 385 bool wxSizer::Remove( wxWindow 
*window 
) 
 387     return Detach( window 
); 
 390 bool wxSizer::Remove( wxSizer 
*sizer 
) 
 392     wxASSERT_MSG( sizer
, _T("Removing NULL sizer") ); 
 394     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 397         wxSizerItem     
*item 
= node
->GetData(); 
 399         if (item
->GetSizer() == sizer
) 
 402             m_children
.Erase( node 
); 
 406         node 
= node
->GetNext(); 
 412 bool wxSizer::Remove( int index 
) 
 414     wxCHECK_MSG( index 
>= 0 && (size_t)index 
< m_children
.GetCount(), 
 416                  _T("Remove index is out of range") ); 
 418     wxSizerItemList::compatibility_iterator node 
= m_children
.Item( index 
); 
 420     wxCHECK_MSG( node
, false, _T("Failed to find child node") ); 
 422     wxSizerItem 
*item 
= node
->GetData(); 
 424     if( item
->IsWindow() ) 
 425         item
->GetWindow()->SetContainingSizer( NULL 
); 
 428     m_children
.Erase( node 
); 
 432 bool wxSizer::Detach( wxSizer 
*sizer 
) 
 434     wxASSERT_MSG( sizer
, _T("Detaching NULL sizer") ); 
 436     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 439         wxSizerItem     
*item 
= node
->GetData(); 
 441         if (item
->GetSizer() == sizer
) 
 445             m_children
.Erase( node 
); 
 448         node 
= node
->GetNext(); 
 454 bool wxSizer::Detach( wxWindow 
*window 
) 
 456     wxASSERT_MSG( window
, _T("Detaching NULL window") ); 
 458     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 461         wxSizerItem     
*item 
= node
->GetData(); 
 463         if (item
->GetWindow() == window
) 
 465             item
->GetWindow()->SetContainingSizer( NULL 
); 
 467             m_children
.Erase( node 
); 
 470         node 
= node
->GetNext(); 
 476 bool wxSizer::Detach( int index 
) 
 478     wxCHECK_MSG( index 
>= 0 && (size_t)index 
< m_children
.GetCount(), 
 480                  _T("Detach index is out of range") ); 
 482     wxSizerItemList::compatibility_iterator node 
= m_children
.Item( index 
); 
 484     wxCHECK_MSG( node
, false, _T("Failed to find child node") ); 
 486     wxSizerItem 
*item 
= node
->GetData(); 
 488     if( item
->IsSizer() ) 
 490     else if( item
->IsWindow() ) 
 491         item
->GetWindow()->SetContainingSizer( NULL 
); 
 494     m_children
.Erase( node 
); 
 498 void wxSizer::Clear( bool delete_windows 
) 
 500     // First clear the ContainingSizer pointers 
 501     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 504         wxSizerItem     
*item 
= node
->GetData(); 
 506         if (item
->IsWindow()) 
 507             item
->GetWindow()->SetContainingSizer( NULL 
); 
 508         node 
= node
->GetNext(); 
 511     // Destroy the windows if needed 
 515     // Now empty the list 
 516     WX_CLEAR_LIST(wxSizerItemList
, m_children
); 
 519 void wxSizer::DeleteWindows() 
 521     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 524         wxSizerItem     
*item 
= node
->GetData(); 
 526         item
->DeleteWindows(); 
 527         node 
= node
->GetNext(); 
 531 wxSize 
wxSizer::Fit( wxWindow 
*window 
) 
 533     wxSize 
size(window
->IsTopLevel() ? FitSize(window
) 
 534                                      : GetMinWindowSize(window
)); 
 536     window
->SetSize( size 
); 
 541 void wxSizer::FitInside( wxWindow 
*window 
) 
 544     if (window
->IsTopLevel()) 
 545         size 
= VirtualFitSize( window 
); 
 547         size 
= GetMinClientSize( window 
); 
 549     window
->SetVirtualSize( size 
); 
 552 void wxSizer::Layout() 
 554     // (re)calculates minimums needed for each item and other preparations 
 558     // Applies the layout and repositions/resizes the items 
 562 void wxSizer::SetSizeHints( wxWindow 
*window 
) 
 564     // Preserve the window's max size hints, but set the 
 565     // lower bound according to the sizer calculations. 
 567     wxSize size 
= Fit( window 
); 
 569     window
->SetSizeHints( size
.x
, 
 571                           window
->GetMaxWidth(), 
 572                           window
->GetMaxHeight() ); 
 575 void wxSizer::SetVirtualSizeHints( wxWindow 
*window 
) 
 577     // Preserve the window's max size hints, but set the 
 578     // lower bound according to the sizer calculations. 
 581     wxSize 
size( window
->GetVirtualSize() ); 
 582     window
->SetVirtualSizeHints( size
.x
, 
 584                                  window
->GetMaxWidth(), 
 585                                  window
->GetMaxHeight() ); 
 588 wxSize 
wxSizer::GetMaxWindowSize( wxWindow 
*window 
) const 
 590     return window
->GetMaxSize(); 
 593 wxSize 
wxSizer::GetMinWindowSize( wxWindow 
*window 
) 
 595     wxSize      
minSize( GetMinSize() ); 
 596     wxSize      
size( window
->GetSize() ); 
 597     wxSize      
client_size( window
->GetClientSize() ); 
 599     return wxSize( minSize
.x
+size
.x
-client_size
.x
, 
 600                    minSize
.y
+size
.y
-client_size
.y 
); 
 603 // TODO on mac we need a function that determines how much free space this 
 604 // min size contains, in order to make sure that we have 20 pixels of free 
 605 // space around the controls 
 607 // Return a window size that will fit within the screens dimensions 
 608 wxSize 
wxSizer::FitSize( wxWindow 
*window 
) 
 610     wxSize size     
= GetMinWindowSize( window 
); 
 611     wxSize sizeMax  
= GetMaxWindowSize( window 
); 
 613     // Limit the size if sizeMax != wxDefaultSize 
 615     if ( size
.x 
> sizeMax
.x 
&& sizeMax
.x 
!= wxDefaultCoord 
) 
 617     if ( size
.y 
> sizeMax
.y 
&& sizeMax
.y 
!= wxDefaultCoord 
) 
 623 wxSize 
wxSizer::GetMaxClientSize( wxWindow 
*window 
) const 
 625     wxSize 
maxSize( window
->GetMaxSize() ); 
 627     if( maxSize 
!= wxDefaultSize 
) 
 629         wxSize 
size( window
->GetSize() ); 
 630         wxSize 
client_size( window
->GetClientSize() ); 
 632         return wxSize( maxSize
.x 
+ client_size
.x 
- size
.x
, 
 633                        maxSize
.y 
+ client_size
.y 
- size
.y 
); 
 636         return wxDefaultSize
; 
 639 wxSize 
wxSizer::GetMinClientSize( wxWindow 
*WXUNUSED(window
) ) 
 641     return GetMinSize();  // Already returns client size. 
 644 wxSize 
wxSizer::VirtualFitSize( wxWindow 
*window 
) 
 646     wxSize size     
= GetMinClientSize( window 
); 
 647     wxSize sizeMax  
= GetMaxClientSize( window 
); 
 649     // Limit the size if sizeMax != wxDefaultSize 
 651     if ( size
.x 
> sizeMax
.x 
&& sizeMax
.x 
!= wxDefaultCoord 
) 
 653     if ( size
.y 
> sizeMax
.y 
&& sizeMax
.y 
!= wxDefaultCoord 
) 
 659 void wxSizer::SetDimension( int x
, int y
, int width
, int height 
) 
 668 wxSize 
wxSizer::GetMinSize() 
 670     wxSize 
ret( CalcMin() ); 
 671     if (ret
.x 
< m_minSize
.x
) ret
.x 
= m_minSize
.x
; 
 672     if (ret
.y 
< m_minSize
.y
) ret
.y 
= m_minSize
.y
; 
 676 void wxSizer::DoSetMinSize( int width
, int height 
) 
 679     m_minSize
.y 
= height
; 
 682 bool wxSizer::DoSetItemMinSize( wxWindow 
*window
, int width
, int height 
) 
 684     wxASSERT_MSG( window
, _T("SetMinSize for NULL window") ); 
 686     // Is it our immediate child? 
 688     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 691         wxSizerItem     
*item 
= node
->GetData(); 
 693         if (item
->GetWindow() == window
) 
 695             item
->SetMinSize( width
, height 
); 
 698         node 
= node
->GetNext(); 
 701     // No?  Search any subsizers we own then 
 703     node 
= m_children
.GetFirst(); 
 706         wxSizerItem     
*item 
= node
->GetData(); 
 708         if ( item
->GetSizer() && 
 709              item
->GetSizer()->DoSetItemMinSize( window
, width
, height 
) ) 
 711             // A child sizer found the requested windw, exit. 
 714         node 
= node
->GetNext(); 
 720 bool wxSizer::DoSetItemMinSize( wxSizer 
*sizer
, int width
, int height 
) 
 722     wxASSERT_MSG( sizer
, _T("SetMinSize for NULL sizer") ); 
 724     // Is it our immediate child? 
 726     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 729         wxSizerItem     
*item 
= node
->GetData(); 
 731         if (item
->GetSizer() == sizer
) 
 733             item
->GetSizer()->DoSetMinSize( width
, height 
); 
 736         node 
= node
->GetNext(); 
 739     // No?  Search any subsizers we own then 
 741     node 
= m_children
.GetFirst(); 
 744         wxSizerItem     
*item 
= node
->GetData(); 
 746         if ( item
->GetSizer() && 
 747              item
->GetSizer()->DoSetItemMinSize( sizer
, width
, height 
) ) 
 749             // A child found the requested sizer, exit. 
 752         node 
= node
->GetNext(); 
 758 bool wxSizer::DoSetItemMinSize( size_t index
, int width
, int height 
) 
 760     wxSizerItemList::compatibility_iterator node 
= m_children
.Item( index 
); 
 762     wxCHECK_MSG( node
, false, _T("Failed to find child node") ); 
 764     wxSizerItem     
*item 
= node
->GetData(); 
 766     if (item
->GetSizer()) 
 768         // Sizers contains the minimal size in them, if not calculated ... 
 769         item
->GetSizer()->DoSetMinSize( width
, height 
); 
 773         // ... but the minimal size of spacers and windows is stored via the item 
 774         item
->SetMinSize( width
, height 
); 
 780 wxSizerItem
* wxSizer::GetItem( wxWindow 
*window
, bool recursive 
) 
 782     wxASSERT_MSG( window
, _T("GetItem for NULL window") ); 
 784     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 787         wxSizerItem     
*item 
= node
->GetData(); 
 789         if (item
->GetWindow() == window
) 
 793         else if (recursive 
&& item
->IsSizer()) 
 795             wxSizerItem 
*subitem 
= item
->GetSizer()->GetItem( window
, true ); 
 800         node 
= node
->GetNext(); 
 806 wxSizerItem
* wxSizer::GetItem( wxSizer 
*sizer
, bool recursive 
) 
 808     wxASSERT_MSG( sizer
, _T("GetItem for NULL sizer") ); 
 810     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 813         wxSizerItem 
*item 
= node
->GetData(); 
 815         if (item
->GetSizer() == sizer
) 
 819         else if (recursive 
&& item
->IsSizer()) 
 821             wxSizerItem 
*subitem 
= item
->GetSizer()->GetItem( sizer
, true ); 
 826         node 
= node
->GetNext(); 
 832 wxSizerItem
* wxSizer::GetItem( size_t index 
) 
 834     wxCHECK_MSG( index 
< m_children
.GetCount(), 
 836                  _T("GetItem index is out of range") ); 
 838     return m_children
.Item( index 
)->GetData(); 
 841 bool wxSizer::Show( wxWindow 
*window
, bool show
, bool recursive 
) 
 843     wxSizerItem 
*item 
= GetItem( window
, recursive 
); 
 854 bool wxSizer::Show( wxSizer 
*sizer
, bool show
, bool recursive 
) 
 856     wxSizerItem 
*item 
= GetItem( sizer
, recursive 
); 
 867 bool wxSizer::Show( size_t index
, bool show
) 
 869     wxSizerItem 
*item 
= GetItem( index 
); 
 880 void wxSizer::ShowItems( bool show 
) 
 882     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 885         node
->GetData()->Show( show 
); 
 886         node 
= node
->GetNext(); 
 890 bool wxSizer::IsShown( wxWindow 
*window 
) const 
 892     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 895         wxSizerItem     
*item 
= node
->GetData(); 
 897         if (item
->GetWindow() == window
) 
 899             return item
->IsShown(); 
 901         node 
= node
->GetNext(); 
 904     wxFAIL_MSG( _T("IsShown failed to find sizer item") ); 
 909 bool wxSizer::IsShown( wxSizer 
*sizer 
) const 
 911     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
 914         wxSizerItem     
*item 
= node
->GetData(); 
 916         if (item
->GetSizer() == sizer
) 
 918             return item
->IsShown(); 
 920         node 
= node
->GetNext(); 
 923     wxFAIL_MSG( _T("IsShown failed to find sizer item") ); 
 928 bool wxSizer::IsShown( size_t index 
) const 
 930     wxCHECK_MSG( index 
< m_children
.GetCount(), 
 932                  _T("IsShown index is out of range") ); 
 934     return m_children
.Item( index 
)->GetData()->IsShown(); 
 938 //--------------------------------------------------------------------------- 
 940 //--------------------------------------------------------------------------- 
 942 wxGridSizer::wxGridSizer( int rows
, int cols
, int vgap
, int hgap 
) 
 948     if (m_rows 
== 0 && m_cols 
== 0) 
 952 wxGridSizer::wxGridSizer( int cols
, int vgap
, int hgap 
) 
 958     if (m_rows 
== 0 && m_cols 
== 0) 
 962 int wxGridSizer::CalcRowsCols(int& nrows
, int& ncols
) const 
 964     int nitems 
= m_children
.GetCount(); 
 970             nrows 
= (nitems 
+ m_cols 
- 1) / m_cols
; 
 974             ncols 
= (nitems 
+ m_rows 
- 1) / m_rows
; 
 977         else // 0 columns, 0 rows? 
 979             wxFAIL_MSG( _T("grid sizer must have either rows or columns fixed") ); 
 988 void wxGridSizer::RecalcSizes() 
 990     int nitems
, nrows
, ncols
; 
 991     if ( (nitems 
= CalcRowsCols(nrows
, ncols
)) == 0 ) 
 994     wxSize 
sz( GetSize() ); 
 995     wxPoint 
pt( GetPosition() ); 
 997     int w 
= (sz
.x 
- (ncols 
- 1) * m_hgap
) / ncols
; 
 998     int h 
= (sz
.y 
- (nrows 
- 1) * m_vgap
) / nrows
; 
1001     for (int c 
= 0; c 
< ncols
; c
++) 
1004         for (int r 
= 0; r 
< nrows
; r
++) 
1006             int i 
= r 
* ncols 
+ c
; 
1009                 wxSizerItemList::compatibility_iterator node 
= m_children
.Item( i 
); 
1011                 wxASSERT_MSG( node
, _T("Failed to find SizerItemList node") ); 
1013                 SetItemBounds( node
->GetData(), x
, y
, w
, h
); 
1021 wxSize 
wxGridSizer::CalcMin() 
1024     if ( CalcRowsCols(nrows
, ncols
) == 0 ) 
1025         return wxSize(10, 10); 
1027     // Find the max width and height for any component 
1031     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
1034         wxSizerItem     
*item 
= node
->GetData(); 
1035         wxSize           
sz( item
->CalcMin() ); 
1037         w 
= wxMax( w
, sz
.x 
); 
1038         h 
= wxMax( h
, sz
.y 
); 
1040         node 
= node
->GetNext(); 
1043     return wxSize( ncols 
* w 
+ (ncols
-1) * m_hgap
, 
1044                    nrows 
* h 
+ (nrows
-1) * m_vgap 
); 
1047 void wxGridSizer::SetItemBounds( wxSizerItem 
*item
, int x
, int y
, int w
, int h 
) 
1050     wxSize 
sz( item
->GetMinSizeWithBorder() ); 
1051     int flag 
= item
->GetFlag(); 
1053     if ((flag 
& wxEXPAND
) || (flag 
& wxSHAPED
)) 
1059         if (flag 
& wxALIGN_CENTER_HORIZONTAL
) 
1061             pt
.x 
= x 
+ (w 
- sz
.x
) / 2; 
1063         else if (flag 
& wxALIGN_RIGHT
) 
1065             pt
.x 
= x 
+ (w 
- sz
.x
); 
1068         if (flag 
& wxALIGN_CENTER_VERTICAL
) 
1070             pt
.y 
= y 
+ (h 
- sz
.y
) / 2; 
1072         else if (flag 
& wxALIGN_BOTTOM
) 
1074             pt
.y 
= y 
+ (h 
- sz
.y
); 
1078     item
->SetDimension(pt
, sz
); 
1081 //--------------------------------------------------------------------------- 
1083 //--------------------------------------------------------------------------- 
1085 wxFlexGridSizer::wxFlexGridSizer( int rows
, int cols
, int vgap
, int hgap 
) 
1086                : wxGridSizer( rows
, cols
, vgap
, hgap 
), 
1087                  m_flexDirection(wxBOTH
), 
1088                  m_growMode(wxFLEX_GROWMODE_SPECIFIED
) 
1092 wxFlexGridSizer::wxFlexGridSizer( int cols
, int vgap
, int hgap 
) 
1093                : wxGridSizer( cols
, vgap
, hgap 
), 
1094                  m_flexDirection(wxBOTH
), 
1095                  m_growMode(wxFLEX_GROWMODE_SPECIFIED
) 
1099 wxFlexGridSizer::~wxFlexGridSizer() 
1103 void wxFlexGridSizer::RecalcSizes() 
1105     int nitems
, nrows
, ncols
; 
1106     if ( (nitems 
= CalcRowsCols(nrows
, ncols
)) == 0 ) 
1109     wxPoint 
pt( GetPosition() ); 
1110     wxSize 
sz( GetSize() ); 
1112     AdjustForGrowables(sz
, m_calculatedMinSize
, nrows
, ncols
); 
1114     sz 
= wxSize( pt
.x 
+ sz
.x
, pt
.y 
+ sz
.y 
); 
1117     for (int c 
= 0; c 
< ncols
; c
++) 
1120         for (int r 
= 0; r 
< nrows
; r
++) 
1122             int i 
= r 
* ncols 
+ c
; 
1125                 wxSizerItemList::compatibility_iterator node 
= m_children
.Item( i 
); 
1127                 wxASSERT_MSG( node
, _T("Failed to find node") ); 
1129                 int w 
= wxMax( 0, wxMin( m_colWidths
[c
], sz
.x 
- x 
) ); 
1130                 int h 
= wxMax( 0, wxMin( m_rowHeights
[r
], sz
.y 
- y 
) ); 
1132                 SetItemBounds( node
->GetData(), x
, y
, w
, h
); 
1134             if (m_rowHeights
[r
] != -1) 
1135                 y 
= y 
+ m_rowHeights
[r
] + m_vgap
; 
1137         if (m_colWidths
[c
] != -1) 
1138             x 
= x 
+ m_colWidths
[c
] + m_hgap
; 
1142 wxSize 
wxFlexGridSizer::CalcMin() 
1148     // Number of rows/columns can change as items are added or removed. 
1149     if ( !CalcRowsCols(nrows
, ncols
) ) 
1150         return wxSize(10, 10); 
1152     m_rowHeights
.SetCount(nrows
); 
1153     m_colWidths
.SetCount(ncols
); 
1155     // We have to recalcuate the sizes in case the item minimum size has 
1156     // changed since the previous layout, or the item has been hidden using 
1157     // wxSizer::Show(). If all the items in a row/column are hidden, the final 
1158     // dimension of the row/column will be -1, indicating that the column 
1159     // itself is hidden. 
1160     for( s 
= m_rowHeights
.GetCount(), i 
= 0; i 
< s
; ++i 
) 
1161         m_rowHeights
[ i 
] = -1; 
1162     for( s 
= m_colWidths
.GetCount(), i 
= 0; i 
< s
; ++i 
) 
1163         m_colWidths
[ i 
] = -1; 
1165     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
1170         wxSizerItem    
*item 
= node
->GetData(); 
1171         if ( item
->IsShown() ) 
1173             wxSize 
sz( item
->CalcMin() ); 
1174             int row 
= i 
/ ncols
; 
1175             int col 
= i 
% ncols
; 
1177             m_rowHeights
[ row 
] = wxMax( wxMax( 0, sz
.y 
), m_rowHeights
[ row 
] ); 
1178             m_colWidths
[ col 
] = wxMax( wxMax( 0, sz
.x 
), m_colWidths
[ col 
] ); 
1181         node 
= node
->GetNext(); 
1185     AdjustForFlexDirection(); 
1187     // Sum total minimum size, including gaps between rows/columns. 
1188     // -1 is used as a magic number meaning empty column. 
1190     for (int col 
= 0; col 
< ncols
; col
++) 
1191         if ( m_colWidths
[ col 
] != -1 ) 
1192             width 
+= m_colWidths
[ col 
] + m_hgap
; 
1197     for (int row 
= 0; row 
< nrows
; row
++) 
1198         if ( m_rowHeights
[ row 
] != -1 ) 
1199             height 
+= m_rowHeights
[ row 
] + m_vgap
; 
1203     m_calculatedMinSize 
= wxSize( width
, height 
); 
1204     return m_calculatedMinSize
; 
1207 void wxFlexGridSizer::AdjustForFlexDirection() 
1209     // the logic in CalcMin works when we resize flexibly in both directions 
1210     // but maybe this is not the case 
1211     if ( m_flexDirection 
!= wxBOTH 
) 
1213         // select the array corresponding to the direction in which we do *not* 
1215         wxArrayInt
& array 
= m_flexDirection 
== wxVERTICAL 
? m_colWidths
 
1218         const int count 
= array
.GetCount(); 
1220         // find the largest value in this array 
1222         for ( n 
= 0; n 
< count
; ++n 
) 
1224             if ( array
[n
] > largest 
) 
1228         // and now fill it with the largest value 
1229         for ( n 
= 0; n 
< count
; ++n 
) 
1237 void wxFlexGridSizer::AdjustForGrowables(const wxSize
& sz
, const wxSize
& minsz
, 
1238                                          int nrows
, int ncols
) 
1240     // what to do with the rows? by default, resize them proportionally 
1241     if ( sz
.y 
> minsz
.y 
&& ( (m_flexDirection 
& wxVERTICAL
) || (m_growMode 
== wxFLEX_GROWMODE_SPECIFIED
) ) ) 
1243         int sum_proportions 
= 0; 
1244         int growable_space 
= 0; 
1247         for (idx 
= 0; idx 
< m_growableRows
.GetCount(); idx
++) 
1249             // Since the number of rows/columns can change as items are 
1250             // inserted/deleted, we need to verify at runtime that the 
1251             // requested growable rows/columns are still valid. 
1252             if (m_growableRows
[idx
] >= nrows
) 
1255             // If all items in a row/column are hidden, that row/column will 
1256             // have a dimension of -1.  This causes the row/column to be 
1257             // hidden completely. 
1258             if (m_rowHeights
[ m_growableRows
[idx
] ] == -1) 
1260             sum_proportions 
+= m_growableRowsProportions
[idx
]; 
1261             growable_space 
+= m_rowHeights
[ m_growableRows
[idx
] ]; 
1267             for (idx 
= 0; idx 
< m_growableRows
.GetCount(); idx
++) 
1269                 if (m_growableRows
[idx
] >= nrows 
) 
1271                 if (m_rowHeights
[ m_growableRows
[idx
] ] == -1) 
1272                     m_rowHeights
[ m_growableRows
[idx
] ] = 0; 
1275                     int delta 
= (sz
.y 
- minsz
.y
); 
1276                     if (sum_proportions 
== 0) 
1277                         delta 
= (delta
/num
) + m_rowHeights
[ m_growableRows
[idx
] ]; 
1279                         delta 
= ((delta
+growable_space
)*m_growableRowsProportions
[idx
]) / sum_proportions
; 
1280                     m_rowHeights
[ m_growableRows
[idx
] ] = delta
; 
1285     else if ( (m_growMode 
== wxFLEX_GROWMODE_ALL
) && (sz
.y 
> minsz
.y
) ) 
1287         // rounding problem? 
1288         for ( int row 
= 0; row 
< nrows
; ++row 
) 
1289             m_rowHeights
[ row 
] = sz
.y 
/ nrows
; 
1292     // the same logic as above but for the columns 
1293     if ( sz
.x 
> minsz
.x 
&& ( (m_flexDirection 
& wxHORIZONTAL
) || (m_growMode 
== wxFLEX_GROWMODE_SPECIFIED
) ) ) 
1295         int sum_proportions 
= 0; 
1296         int growable_space 
= 0; 
1299         for (idx 
= 0; idx 
< m_growableCols
.GetCount(); idx
++) 
1301             // Since the number of rows/columns can change as items are 
1302             // inserted/deleted, we need to verify at runtime that the 
1303             // requested growable rows/columns are still valid. 
1304             if (m_growableCols
[idx
] >= ncols
) 
1307             // If all items in a row/column are hidden, that row/column will 
1308             // have a dimension of -1.  This causes the column to be hidden 
1310             if (m_colWidths
[ m_growableCols
[idx
] ] == -1) 
1312             sum_proportions 
+= m_growableColsProportions
[idx
]; 
1313             growable_space 
+= m_colWidths
[ m_growableCols
[idx
] ]; 
1319             for (idx 
= 0; idx 
< m_growableCols
.GetCount(); idx
++) 
1321                 if (m_growableCols
[idx
] >= ncols 
) 
1323                 if (m_colWidths
[ m_growableCols
[idx
] ] == -1) 
1324                     m_colWidths
[ m_growableCols
[idx
] ] = 0; 
1327                     int delta 
= (sz
.x 
- minsz
.x
); 
1328                     if (sum_proportions 
== 0) 
1329                         delta 
= (delta
/num
) + m_colWidths
[ m_growableCols
[idx
] ]; 
1331                         delta 
= ((delta
+growable_space
)*m_growableColsProportions
[idx
])/sum_proportions
; 
1332                     m_colWidths
[ m_growableCols
[idx
] ] = delta
; 
1337     else if ( (m_growMode 
== wxFLEX_GROWMODE_ALL
) && (sz
.x 
> minsz
.x
) ) 
1339         for ( int col
=0; col 
< ncols
; ++col 
) 
1340             m_colWidths
[ col 
] = sz
.x 
/ ncols
; 
1345 void wxFlexGridSizer::AddGrowableRow( size_t idx
, int proportion 
) 
1347     m_growableRows
.Add( idx 
); 
1348     m_growableRowsProportions
.Add( proportion 
); 
1351 void wxFlexGridSizer::RemoveGrowableRow( size_t idx 
) 
1353     m_growableRows
.Remove( idx 
); 
1356 void wxFlexGridSizer::AddGrowableCol( size_t idx
, int proportion 
) 
1358     m_growableCols
.Add( idx 
); 
1359     m_growableColsProportions
.Add( proportion 
); 
1362 void wxFlexGridSizer::RemoveGrowableCol( size_t idx 
) 
1364     m_growableCols
.Remove( idx 
); 
1367 //--------------------------------------------------------------------------- 
1369 //--------------------------------------------------------------------------- 
1371 wxBoxSizer::wxBoxSizer( int orient 
) 
1372     : m_orient( orient 
) 
1376 void wxBoxSizer::RecalcSizes() 
1378     if (m_children
.GetCount() == 0) 
1384         if (m_orient 
== wxHORIZONTAL
) 
1385             delta 
= m_size
.x 
- m_fixedWidth
; 
1387             delta 
= m_size
.y 
- m_fixedHeight
; 
1390     wxPoint 
pt( m_position 
); 
1392     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
1395         wxSizerItem     
*item 
= node
->GetData(); 
1397         if (item
->IsShown()) 
1399             wxSize 
size( item
->GetMinSizeWithBorder() ); 
1401             if (m_orient 
== wxVERTICAL
) 
1403                 wxCoord height 
= size
.y
; 
1404                 if (item
->GetProportion()) 
1406                     // Because of at least one visible item has non-zero 
1407                     // proportion then m_stretchable is not zero 
1408                     height 
= (delta 
* item
->GetProportion()) / m_stretchable
; 
1411                 wxPoint 
child_pos( pt 
); 
1412                 wxSize  
child_size( size
.x
, height 
); 
1414                 if (item
->GetFlag() & (wxEXPAND 
| wxSHAPED
)) 
1415                     child_size
.x 
= m_size
.x
; 
1416                 else if (item
->GetFlag() & wxALIGN_RIGHT
) 
1417                     child_pos
.x 
+= m_size
.x 
- size
.x
; 
1418                 else if (item
->GetFlag() & (wxCENTER 
| wxALIGN_CENTER_HORIZONTAL
)) 
1419                 // XXX wxCENTER is added for backward compatibility; 
1420                 //     wxALIGN_CENTER should be used in new code 
1421                     child_pos
.x 
+= (m_size
.x 
- size
.x
) / 2; 
1423                 item
->SetDimension( child_pos
, child_size 
); 
1429                 wxCoord width 
= size
.x
; 
1430                 if (item
->GetProportion()) 
1432                     // Because of at least one visible item has non-zero 
1433                     // proportion then m_stretchable is not zero 
1434                     width 
= (delta 
* item
->GetProportion()) / m_stretchable
; 
1437                 wxPoint 
child_pos( pt 
); 
1438                 wxSize  
child_size( width
, size
.y 
); 
1440                 if (item
->GetFlag() & (wxEXPAND 
| wxSHAPED
)) 
1441                     child_size
.y 
= m_size
.y
; 
1442                 else if (item
->GetFlag() & wxALIGN_BOTTOM
) 
1443                     child_pos
.y 
+= m_size
.y 
- size
.y
; 
1444                 else if (item
->GetFlag() & (wxCENTER 
| wxALIGN_CENTER_VERTICAL
)) 
1445                 // XXX wxCENTER is added for backward compatibility; 
1446                 //     wxALIGN_CENTER should be used in new code 
1447                     child_pos
.y 
+= (m_size
.y 
- size
.y
) / 2; 
1449                 item
->SetDimension( child_pos
, child_size 
); 
1455         node 
= node
->GetNext(); 
1459 wxSize 
wxBoxSizer::CalcMin() 
1461     if (m_children
.GetCount() == 0) 
1462         return wxSize(10,10); 
1470     // precalc item minsizes and count proportions 
1471     wxSizerItemList::compatibility_iterator node 
= m_children
.GetFirst(); 
1474         wxSizerItem 
*item 
= node
->GetData(); 
1476         if (item
->IsShown()) 
1477             item
->CalcMin();  // result is stored in the item 
1479         if (item
->IsShown() && item
->GetProportion() != 0) 
1480             m_stretchable 
+= item
->GetProportion(); 
1482         node 
= node
->GetNext(); 
1485     // Total minimum size (width or height) of sizer 
1488     node 
= m_children
.GetFirst(); 
1491         wxSizerItem 
*item 
= node
->GetData(); 
1493         if (item
->IsShown() && item
->GetProportion() != 0) 
1495             int stretch 
= item
->GetProportion(); 
1496             wxSize 
size( item
->GetMinSizeWithBorder() ); 
1499             // Integer division rounded up is (a + b - 1) / b 
1500             // Round up needed in order to guarantee that all 
1501             // all items will have size not less then their min size 
1502             if (m_orient 
== wxHORIZONTAL
) 
1503                 minSize 
= ( size
.x
*m_stretchable 
+ stretch 
- 1)/stretch
; 
1505                 minSize 
= ( size
.y
*m_stretchable 
+ stretch 
- 1)/stretch
; 
1507             if (minSize 
> maxMinSize
) 
1508                 maxMinSize 
= minSize
; 
1510         node 
= node
->GetNext(); 
1513     // Calculate overall minimum size 
1514     node 
= m_children
.GetFirst(); 
1517         wxSizerItem 
*item 
= node
->GetData(); 
1519         if (item
->IsShown()) 
1521             wxSize 
size( item
->GetMinSizeWithBorder() ); 
1522             if (item
->GetProportion() != 0) 
1524                 if (m_orient 
== wxHORIZONTAL
) 
1525                     size
.x 
= (maxMinSize
*item
->GetProportion())/m_stretchable
; 
1527                     size
.y 
= (maxMinSize
*item
->GetProportion())/m_stretchable
; 
1531                 if (m_orient 
== wxVERTICAL
) 
1533                     m_fixedHeight 
+= size
.y
; 
1534                     m_fixedWidth 
= wxMax( m_fixedWidth
, size
.x 
); 
1538                     m_fixedWidth 
+= size
.x
; 
1539                     m_fixedHeight 
= wxMax( m_fixedHeight
, size
.y 
); 
1543             if (m_orient 
== wxHORIZONTAL
) 
1545                 m_minWidth 
+= size
.x
; 
1546                 m_minHeight 
= wxMax( m_minHeight
, size
.y 
); 
1550                 m_minHeight 
+= size
.y
; 
1551                 m_minWidth 
= wxMax( m_minWidth
, size
.x 
); 
1554         node 
= node
->GetNext(); 
1557     return wxSize( m_minWidth
, m_minHeight 
); 
1560 //--------------------------------------------------------------------------- 
1562 //--------------------------------------------------------------------------- 
1566 wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox 
*box
, int orient 
) 
1567     : wxBoxSizer( orient 
) 
1568     , m_staticBox( box 
) 
1570     wxASSERT_MSG( box
, wxT("wxStaticBoxSizer needs a static box") ); 
1573 wxStaticBoxSizer::wxStaticBoxSizer(int orient
, wxWindow 
*win
, const wxString
& s
) 
1574                 : wxBoxSizer(orient
), 
1575                   m_staticBox(new wxStaticBox(win
, wxID_ANY
, s
)) 
1579 static void GetStaticBoxBorders( wxStaticBox 
*box
, 
1583     // this has to be done platform by platform as there is no way to 
1584     // guess the thickness of a wxStaticBox border 
1586     box
->GetBordersForSizer(borderTop
,borderOther
); 
1587 #elif defined(__WXMAC__) 
1589     static int extraTop 
= -1; // Uninitted 
1590     static int other 
= 5; 
1592     if ( extraTop 
== -1 ) 
1594         // The minimal border used for the top. Later on the staticbox' 
1595         // font height is added to this. 
1598         if ( UMAGetSystemVersion() >= 0x1030 /*Panther*/ ) 
1600             // As indicated by the HIG, Panther needs an extra border of 11 
1601             // pixels (otherwise overlapping occurs at the top). The "other" 
1602             // border has to be 11. 
1609     *borderTop 
= extraTop 
+ box
->GetCharHeight(); 
1610     *borderOther 
= other
; 
1614     if ( box
->GetLabel().empty() ) 
1618         *borderTop 
= box
->GetCharHeight(); 
1621 #endif // __WXCOCOA__ 
1624 void wxStaticBoxSizer::RecalcSizes() 
1626     int top_border
, other_border
; 
1627     GetStaticBoxBorders(m_staticBox
, &top_border
, &other_border
); 
1629     m_staticBox
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y 
); 
1631     wxPoint 
old_pos( m_position 
); 
1632     m_position
.x 
+= other_border
; 
1633     m_position
.y 
+= top_border
; 
1634     wxSize 
old_size( m_size 
); 
1635     m_size
.x 
-= 2*other_border
; 
1636     m_size
.y 
-= top_border 
+ other_border
; 
1638     wxBoxSizer::RecalcSizes(); 
1640     m_position 
= old_pos
; 
1644 wxSize 
wxStaticBoxSizer::CalcMin() 
1646     int top_border
, other_border
; 
1647     GetStaticBoxBorders(m_staticBox
, &top_border
, &other_border
); 
1649     wxSize 
ret( wxBoxSizer::CalcMin() ); 
1650     ret
.x 
+= 2*other_border
; 
1651     ret
.y 
+= other_border 
+ top_border
; 
1656 void wxStaticBoxSizer::ShowItems( bool show 
) 
1658     m_staticBox
->Show( show 
); 
1659     wxBoxSizer::ShowItems( show 
); 
1662 #endif // wxUSE_STATBOX 
1666 wxStdDialogButtonSizer::wxStdDialogButtonSizer() 
1667     : wxBoxSizer(wxHORIZONTAL
) 
1669     // Vertical buttons with lots of space on either side 
1670     // looks rubbish on WinCE, so let's not do this for now. 
1671     // If we are going to use vertical buttons, we should 
1672     // put the sizer to the right of other controls in the dialog, 
1673     // and that's beyond the scope of this sizer. 
1675     bool is_pda 
= (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
); 
1676     // If we have a PDA screen, put yes/no button over 
1677     // all other buttons, otherwise on the left side. 
1679         m_orient 
= wxVERTICAL
; 
1682     m_buttonAffirmative 
= NULL
; 
1683     m_buttonApply 
= NULL
; 
1684     m_buttonNegative 
= NULL
; 
1685     m_buttonCancel 
= NULL
; 
1686     m_buttonHelp 
= NULL
; 
1689 void wxStdDialogButtonSizer::AddButton(wxButton 
*mybutton
) 
1691     switch (mybutton
->GetId()) 
1696             m_buttonAffirmative 
= mybutton
; 
1699             m_buttonApply 
= mybutton
; 
1702             m_buttonNegative 
= mybutton
; 
1705             m_buttonCancel 
= mybutton
; 
1708         case wxID_CONTEXT_HELP
: 
1709             m_buttonHelp 
= mybutton
; 
1716 void wxStdDialogButtonSizer::SetAffirmativeButton( wxButton 
*button 
) 
1718     m_buttonAffirmative 
= button
; 
1721 void wxStdDialogButtonSizer::SetNegativeButton( wxButton 
*button 
) 
1723     m_buttonNegative 
= button
; 
1726 void wxStdDialogButtonSizer::SetCancelButton( wxButton 
*button 
) 
1728     m_buttonCancel 
= button
; 
1731 void wxStdDialogButtonSizer::Finalise() 
1734         Add(0, 0, 0, wxLEFT
, 6); 
1736             Add((wxWindow
*)m_buttonHelp
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 6); 
1738         if (m_buttonNegative
){ 
1739             // HIG POLICE BULLETIN - destructive buttons need extra padding 
1740             // 24 pixels on either side 
1741             Add((wxWindow
*)m_buttonNegative
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 12); 
1744         // extra whitespace between help/negative and cancel/ok buttons 
1745         Add(0, 0, 1, wxEXPAND
, 0); 
1747         if (m_buttonCancel
){ 
1748             Add((wxWindow
*)m_buttonCancel
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 6); 
1749             // Cancel or help should be default 
1750             // m_buttonCancel->SetDefaultButton(); 
1753         // Ugh, Mac doesn't really have apply dialogs, so I'll just 
1754         // figure the best place is between Cancel and OK 
1756             Add((wxWindow
*)m_buttonApply
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 6); 
1758         if (m_buttonAffirmative
){ 
1759             Add((wxWindow
*)m_buttonAffirmative
, 0, wxALIGN_CENTRE 
| wxLEFT
, 6); 
1761             if (m_buttonAffirmative
->GetId() == wxID_SAVE
){ 
1762                 // these buttons have set labels under Mac so we should use them 
1763                 m_buttonAffirmative
->SetLabel(_("Save")); 
1764                 m_buttonNegative
->SetLabel(_("Don't Save")); 
1768         // Extra space around and at the right 
1770 #elif defined(__WXGTK20__) 
1771         Add(0, 0, 0, wxLEFT
, 9); 
1773             Add((wxWindow
*)m_buttonHelp
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 3); 
1775         // extra whitespace between help and cancel/ok buttons 
1776         Add(0, 0, 1, wxEXPAND
, 0); 
1778         if (m_buttonNegative
){ 
1779             Add((wxWindow
*)m_buttonNegative
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 3); 
1782         if (m_buttonCancel
){ 
1783             Add((wxWindow
*)m_buttonCancel
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 3); 
1784             // Cancel or help should be default 
1785             // m_buttonCancel->SetDefaultButton(); 
1789             Add((wxWindow
*)m_buttonApply
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, 3); 
1791         if (m_buttonAffirmative
) 
1792             Add((wxWindow
*)m_buttonAffirmative
, 0, wxALIGN_CENTRE 
| wxLEFT
, 6); 
1794     // do the same thing for GTK1 and Windows platforms 
1795     // and assume any platform not accounted for here will use 
1797         Add(0, 0, 0, wxLEFT
, 9); 
1799             Add((wxWindow
*)m_buttonHelp
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, m_buttonHelp
->ConvertDialogToPixels(wxSize(4, 0)).x
); 
1801         // extra whitespace between help and cancel/ok buttons 
1802         Add(0, 0, 1, wxEXPAND
, 0); 
1805             Add((wxWindow
*)m_buttonApply
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, m_buttonApply
->ConvertDialogToPixels(wxSize(4, 0)).x
); 
1807         if (m_buttonAffirmative
){ 
1808             Add((wxWindow
*)m_buttonAffirmative
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, m_buttonAffirmative
->ConvertDialogToPixels(wxSize(4, 0)).x
); 
1811         if (m_buttonNegative
){ 
1812             Add((wxWindow
*)m_buttonNegative
, 0, wxALIGN_CENTRE 
| wxLEFT 
| wxRIGHT
, m_buttonNegative
->ConvertDialogToPixels(wxSize(4, 0)).x
); 
1815         if (m_buttonCancel
){ 
1816             Add((wxWindow
*)m_buttonCancel
, 0, wxALIGN_CENTRE 
| wxLEFT
, m_buttonCancel
->ConvertDialogToPixels(wxSize(4, 0)).x
); 
1817             // Cancel or help should be default 
1818             // m_buttonCancel->SetDefaultButton(); 
1824 #endif // wxUSE_BUTTON 
1826 #if WXWIN_COMPATIBILITY_2_4 
1828 // ---------------------------------------------------------------------------- 
1830 // ---------------------------------------------------------------------------- 
1833 IMPLEMENT_CLASS(wxBookCtrlSizer
, wxSizer
) 
1835 IMPLEMENT_CLASS(wxNotebookSizer
, wxBookCtrlSizer
) 
1836 #endif // wxUSE_NOTEBOOK 
1837 #endif // wxUSE_BOOKCTRL 
1841 wxBookCtrlSizer::wxBookCtrlSizer(wxBookCtrlBase 
*bookctrl
) 
1842                : m_bookctrl(bookctrl
) 
1844     wxASSERT_MSG( bookctrl
, wxT("wxBookCtrlSizer needs a control") ); 
1847 void wxBookCtrlSizer::RecalcSizes() 
1849     m_bookctrl
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y 
); 
1852 wxSize 
wxBookCtrlSizer::CalcMin() 
1854     wxSize sizeBorder 
= m_bookctrl
->CalcSizeFromPage(wxSize(0,0)); 
1859     if ( m_bookctrl
->GetPageCount() == 0 ) 
1861         return wxSize(sizeBorder
.x 
+ 10, sizeBorder
.y 
+ 10); 
1867     wxWindowList::compatibility_iterator
 
1868         node 
= m_bookctrl
->GetChildren().GetFirst(); 
1871         wxWindow 
*item 
= node
->GetData(); 
1872         wxSizer 
*itemsizer 
= item
->GetSizer(); 
1876             wxSize 
subsize( itemsizer
->CalcMin() ); 
1878             if (subsize
.x 
> maxX
) 
1880             if (subsize
.y 
> maxY
) 
1884         node 
= node
->GetNext(); 
1887     return wxSize( maxX
, maxY 
) + sizeBorder
; 
1892 wxNotebookSizer::wxNotebookSizer(wxNotebook 
*nb
) 
1894     wxASSERT_MSG( nb
, wxT("wxNotebookSizer needs a control") ); 
1898 #endif // wxUSE_NOTEBOOOK 
1899 #endif // wxUSE_BOOKCTRL 
1901 #endif // WXWIN_COMPATIBILITY_2_4