1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: provide new wxSizer class for layout
4 // Author: Robert Roebling and Robin Dunn
5 // Modified by: Ron Lee
8 // Copyright: (c) Robin Dunn, Dirk Holtwick and Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "sizer.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
25 #include "wx/statbox.h"
26 #include "wx/notebook.h"
28 //---------------------------------------------------------------------------
30 IMPLEMENT_ABSTRACT_CLASS(wxSizerItem
, wxObject
)
31 IMPLEMENT_ABSTRACT_CLASS(wxSizer
, wxObject
)
32 IMPLEMENT_ABSTRACT_CLASS(wxGridSizer
, wxSizer
)
33 IMPLEMENT_ABSTRACT_CLASS(wxFlexGridSizer
, wxGridSizer
)
34 IMPLEMENT_ABSTRACT_CLASS(wxBoxSizer
, wxSizer
)
36 IMPLEMENT_ABSTRACT_CLASS(wxStaticBoxSizer
, wxBoxSizer
)
39 IMPLEMENT_ABSTRACT_CLASS(wxNotebookSizer
, wxSizer
)
42 //---------------------------------------------------------------------------
44 //---------------------------------------------------------------------------
46 wxSizerItem::wxSizerItem( int width
, int height
, int option
, int flag
, int border
, wxObject
* userData
)
48 m_window
= (wxWindow
*) NULL
;
49 m_sizer
= (wxSizer
*) NULL
;
53 m_show
= TRUE
; // Cannot be changed
54 m_userData
= userData
;
56 // minimal size is the initial size
60 SetRatio(width
, height
);
62 // size is set directly
66 wxSizerItem::wxSizerItem( wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
69 m_sizer
= (wxSizer
*) NULL
;
74 m_userData
= userData
;
76 // minimal size is the initial size
77 m_minSize
= window
->GetSize();
79 // aspect ratio calculated from initial size
82 // size is calculated later
86 wxSizerItem::wxSizerItem( wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
88 m_window
= (wxWindow
*) NULL
;
94 m_userData
= userData
;
96 // minimal size is calculated later
100 // size is calculated later
104 wxSizerItem::~wxSizerItem()
113 wxSize
wxSizerItem::GetSize()
117 ret
= m_sizer
->GetSize();
120 ret
= m_window
->GetSize();
127 if (m_flag
& wxNORTH
)
129 if (m_flag
& wxSOUTH
)
135 wxSize
wxSizerItem::CalcMin()
140 ret
= m_sizer
->GetMinSize();
142 // if we have to preserve aspect ratio _AND_ this is
143 // the first-time calculation, consider ret to be initial size
144 if ((m_flag
& wxSHAPED
) && !m_ratio
)
149 if ( IsWindow() && (m_flag
& wxADJUST_MINSIZE
) )
151 // By user request, keep the minimal size for this item
152 // in sync with the largest of BestSize and any user supplied
153 // minimum size hint. Useful in cases where the item is
154 // changeable -- static text labels, etc.
155 m_minSize
= m_window
->GetAdjustedBestSize();
165 if (m_flag
& wxNORTH
)
167 if (m_flag
& wxSOUTH
)
173 void wxSizerItem::SetDimension( wxPoint pos
, wxSize size
)
175 if (m_flag
& wxSHAPED
)
177 // adjust aspect ratio
178 int rwidth
= (int) (size
.y
* m_ratio
);
182 int rheight
= (int) (size
.x
/ m_ratio
);
183 // add vertical space
184 if (m_flag
& wxALIGN_CENTER_VERTICAL
)
185 pos
.y
+= (size
.y
- rheight
) / 2;
186 else if (m_flag
& wxALIGN_BOTTOM
)
187 pos
.y
+= (size
.y
- rheight
);
188 // use reduced dimensions
191 else if (rwidth
< size
.x
)
193 // add horizontal space
194 if (m_flag
& wxALIGN_CENTER_HORIZONTAL
)
195 pos
.x
+= (size
.x
- rwidth
) / 2;
196 else if (m_flag
& wxALIGN_RIGHT
)
197 pos
.x
+= (size
.x
- rwidth
);
202 // This is what GetPosition() returns. Since we calculate
203 // borders afterwards, GetPosition() will be the left/top
204 // corner of the surrounding border.
216 if (m_flag
& wxNORTH
)
221 if (m_flag
& wxSOUTH
)
227 m_sizer
->SetDimension( pos
.x
, pos
.y
, size
.x
, size
.y
);
230 m_window
->SetSize( pos
.x
, pos
.y
, size
.x
, size
.y
, wxSIZE_ALLOW_MINUS_ONE
);
235 void wxSizerItem::DeleteWindows()
241 m_sizer
->DeleteWindows();
244 bool wxSizerItem::IsWindow()
246 return (m_window
!= NULL
);
249 bool wxSizerItem::IsSizer()
251 return (m_sizer
!= NULL
);
254 bool wxSizerItem::IsSpacer()
256 return (m_window
== NULL
) && (m_sizer
== NULL
);
259 //---------------------------------------------------------------------------
261 //---------------------------------------------------------------------------
265 m_children
.DeleteContents( TRUE
);
275 void wxSizer::Add( wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
277 m_children
.Append( new wxSizerItem( window
, option
, flag
, border
, userData
) );
278 window
->SetContainingSizer(this);
281 void wxSizer::Add( wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
283 m_children
.Append( new wxSizerItem( sizer
, option
, flag
, border
, userData
) );
286 void wxSizer::Add( int width
, int height
, int option
, int flag
, int border
, wxObject
* userData
)
288 m_children
.Append( new wxSizerItem( width
, height
, option
, flag
, border
, userData
) );
291 void wxSizer::Prepend( wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
293 m_children
.Insert( new wxSizerItem( window
, option
, flag
, border
, userData
) );
294 window
->SetContainingSizer(this);
297 void wxSizer::Prepend( wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
299 m_children
.Insert( new wxSizerItem( sizer
, option
, flag
, border
, userData
) );
302 void wxSizer::Prepend( int width
, int height
, int option
, int flag
, int border
, wxObject
* userData
)
304 m_children
.Insert( new wxSizerItem( width
, height
, option
, flag
, border
, userData
) );
307 void wxSizer::Insert( int before
, wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
309 m_children
.Insert( before
, new wxSizerItem( window
, option
, flag
, border
, userData
) );
310 window
->SetContainingSizer(this);
313 void wxSizer::Insert( int before
, wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
315 m_children
.Insert( before
, new wxSizerItem( sizer
, option
, flag
, border
, userData
) );
318 void wxSizer::Insert( int before
, int width
, int height
, int option
, int flag
, int border
, wxObject
* userData
)
320 m_children
.Insert( before
, new wxSizerItem( width
, height
, option
, flag
, border
, userData
) );
323 bool wxSizer::Remove( wxWindow
*window
)
327 wxNode
*node
= m_children
.First();
330 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
331 if (item
->GetWindow() == window
)
333 item
->GetWindow()->SetContainingSizer(NULL
);
334 m_children
.DeleteNode( node
);
343 bool wxSizer::Remove( wxSizer
*sizer
)
347 wxNode
*node
= m_children
.First();
350 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
351 if (item
->GetSizer() == sizer
)
353 m_children
.DeleteNode( node
);
362 bool wxSizer::Remove( int pos
)
364 if ((size_t)pos
>= m_children
.GetCount())
366 wxNode
*node
= m_children
.Nth( pos
);
367 if (!node
) return FALSE
;
369 m_children
.DeleteNode( node
);
374 void wxSizer::Clear( bool delete_windows
)
376 // First clear the ContainingSizer pointers
377 wxNode
*node
= m_children
.First();
380 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
381 if (item
->IsWindow())
382 item
->GetWindow()->SetContainingSizer(NULL
);
386 // Destroy the windows if needed
390 // Now empty the list
394 void wxSizer::DeleteWindows()
396 wxNode
*node
= m_children
.First();
399 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
400 item
->DeleteWindows();
405 wxSize
wxSizer::Fit( wxWindow
*window
)
408 if (window
->IsTopLevel())
409 size
= FitSize( window
);
411 size
= GetMinWindowSize( window
);
413 window
->SetSize( size
);
418 void wxSizer::FitInside( wxWindow
*window
)
421 if (window
->IsTopLevel())
422 size
= VirtualFitSize( window
);
424 size
= GetMinClientSize( window
);
426 window
->SetVirtualSize( size
);
429 void wxSizer::Layout()
435 void wxSizer::SetSizeHints( wxWindow
*window
)
437 // Preserve the window's max size hints, but set the
438 // lower bound according to the sizer calculations.
440 wxSize size
= Fit( window
);
442 window
->SetSizeHints( size
.x
,
444 window
->GetMaxWidth(),
445 window
->GetMaxHeight() );
448 void wxSizer::SetVirtualSizeHints( wxWindow
*window
)
450 // Preserve the window's max size hints, but set the
451 // lower bound according to the sizer calculations.
454 wxSize
size( window
->GetVirtualSize() );
455 window
->SetVirtualSizeHints( size
.x
,
457 window
->GetMaxWidth(),
458 window
->GetMaxHeight() );
461 wxSize
wxSizer::GetMaxWindowSize( wxWindow
*window
)
463 return window
->GetMaxSize();
466 wxSize
wxSizer::GetMinWindowSize( wxWindow
*window
)
468 wxSize
minSize( GetMinSize() );
469 wxSize
size( window
->GetSize() );
470 wxSize
client_size( window
->GetClientSize() );
471 return wxSize( minSize
.x
+size
.x
-client_size
.x
,
472 minSize
.y
+size
.y
-client_size
.y
);
475 // Return a window size that will fit within the screens dimensions
476 wxSize
wxSizer::FitSize( wxWindow
*window
)
478 wxSize size
= GetMinWindowSize( window
);
479 wxSize sizeMax
= GetMaxWindowSize( window
);
481 // Limit the size if sizeMax != wxDefaultSize
483 if ( size
.x
> sizeMax
.x
&& sizeMax
.x
!= -1 )
485 if ( size
.y
> sizeMax
.y
&& sizeMax
.y
!= -1 )
491 wxSize
wxSizer::GetMaxClientSize( wxWindow
*window
)
493 wxSize
maxSize( window
->GetMaxSize() );
495 if( maxSize
!= wxDefaultSize
)
497 wxSize
size( window
->GetSize() );
498 wxSize
client_size( window
->GetClientSize() );
500 return wxSize( maxSize
.x
+ client_size
.x
- size
.x
,
501 maxSize
.y
+ client_size
.y
- size
.y
);
504 return wxDefaultSize
;
507 wxSize
wxSizer::GetMinClientSize( wxWindow
*WXUNUSED(window
) )
509 return GetMinSize(); // Already returns client size.
512 wxSize
wxSizer::VirtualFitSize( wxWindow
*window
)
514 wxSize size
= GetMinClientSize( window
);
515 wxSize sizeMax
= GetMaxClientSize( window
);
517 // Limit the size if sizeMax != wxDefaultSize
519 if ( size
.x
> sizeMax
.x
&& sizeMax
.x
!= -1 )
521 if ( size
.y
> sizeMax
.y
&& sizeMax
.y
!= -1 )
527 void wxSizer::SetDimension( int x
, int y
, int width
, int height
)
536 wxSize
wxSizer::GetMinSize()
538 wxSize
ret( CalcMin() );
539 if (ret
.x
< m_minSize
.x
) ret
.x
= m_minSize
.x
;
540 if (ret
.y
< m_minSize
.y
) ret
.y
= m_minSize
.y
;
544 void wxSizer::DoSetMinSize( int width
, int height
)
547 m_minSize
.y
= height
;
550 bool wxSizer::DoSetItemMinSize( wxWindow
*window
, int width
, int height
)
554 wxNode
*node
= m_children
.First();
557 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
558 if (item
->GetWindow() == window
)
560 item
->SetInitSize( width
, height
);
566 node
= m_children
.First();
569 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
570 if (item
->GetSizer())
572 // It's a sizer, so lets search recursively.
573 if (item
->GetSizer()->DoSetItemMinSize( window
, width
, height
))
575 // A child sizer found the requested windw, exit.
585 bool wxSizer::DoSetItemMinSize( wxSizer
*sizer
, int width
, int height
)
589 wxNode
*node
= m_children
.First();
592 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
593 if (item
->GetSizer() == sizer
)
595 item
->GetSizer()->DoSetMinSize( width
, height
);
601 node
= m_children
.First();
604 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
605 if (item
->GetSizer())
607 // It's a sizer, so lets search recursively.
608 if (item
->GetSizer()->DoSetItemMinSize( sizer
, width
, height
))
610 // A child sizer found the requested windw, exit.
620 bool wxSizer::DoSetItemMinSize( int pos
, int width
, int height
)
622 wxNode
*node
= m_children
.Nth( pos
);
623 if (!node
) return FALSE
;
625 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
626 if (item
->GetSizer())
628 // Sizers contains the minimal size in them, if not calculated ...
629 item
->GetSizer()->DoSetMinSize( width
, height
);
633 // ... but the minimal size of spacers and windows in stored in them
634 item
->SetInitSize( width
, height
);
640 void wxSizer::Show(wxWindow
*window
, bool show
)
642 wxNode
*node
= m_children
.GetFirst();
645 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
647 if (item
->IsWindow() && item
->GetWindow() == window
)
657 void wxSizer::Show(wxSizer
*sizer
, bool show
)
659 wxNode
*node
= m_children
.GetFirst();
662 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
664 if (item
->IsSizer() && item
->GetSizer() == sizer
)
667 sizer
->ShowItems(show
);
674 void wxSizer::ShowItems (bool show
)
676 wxNode
*node
= m_children
.GetFirst();
679 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
681 if (item
->IsWindow())
682 item
->GetWindow()->Show (show
);
683 else if (item
->IsSizer())
684 item
->GetSizer()->ShowItems (show
);
690 bool wxSizer::IsShown (wxWindow
*window
)
692 wxNode
*node
= m_children
.GetFirst();
695 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
697 if (item
->IsWindow() && item
->GetWindow() == window
)
699 return item
->IsShown();
707 bool wxSizer::IsShown (wxSizer
*sizer
)
709 wxNode
*node
= m_children
.GetFirst();
712 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
714 if (item
->IsSizer() && item
->GetSizer() == sizer
)
716 return item
->IsShown();
724 //---------------------------------------------------------------------------
726 //---------------------------------------------------------------------------
728 wxGridSizer::wxGridSizer( int rows
, int cols
, int vgap
, int hgap
)
736 wxGridSizer::wxGridSizer( int cols
, int vgap
, int hgap
)
744 int wxGridSizer::CalcRowsCols(int& nrows
, int& ncols
) const
746 int nitems
= m_children
.GetCount();
752 nrows
= (nitems
+ m_cols
- 1) / m_cols
;
756 ncols
= (nitems
+ m_rows
- 1) / m_rows
;
759 else // 0 columns, 0 rows?
761 wxFAIL_MSG( _T("grid sizer must have either rows or columns fixed") );
770 void wxGridSizer::RecalcSizes()
772 int nitems
, nrows
, ncols
;
773 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
776 wxSize
sz( GetSize() );
777 wxPoint
pt( GetPosition() );
779 int w
= (sz
.x
- (ncols
- 1) * m_hgap
) / ncols
;
780 int h
= (sz
.y
- (nrows
- 1) * m_vgap
) / nrows
;
783 for (int c
= 0; c
< ncols
; c
++)
786 for (int r
= 0; r
< nrows
; r
++)
788 int i
= r
* ncols
+ c
;
791 wxNode
*node
= m_children
.Nth( i
);
794 SetItemBounds( (wxSizerItem
*) node
->Data(), x
, y
, w
, h
);
802 wxSize
wxGridSizer::CalcMin()
804 int nitems
, nrows
, ncols
;
805 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
806 return wxSize(10, 10);
808 // Find the max width and height for any component
812 wxNode
*node
= m_children
.First();
815 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
816 wxSize
sz( item
->CalcMin() );
817 w
= wxMax( w
, sz
.x
);
818 h
= wxMax( h
, sz
.y
);
823 return wxSize(ncols
* w
+ (ncols
-1) * m_hgap
,
824 nrows
* h
+ (nrows
-1) * m_vgap
);
827 void wxGridSizer::SetItemBounds( wxSizerItem
*item
, int x
, int y
, int w
, int h
)
830 wxSize
sz( item
->CalcMin() );
831 int flag
= item
->GetFlag();
833 if ((flag
& wxEXPAND
) || (flag
& wxSHAPED
))
839 if (flag
& wxALIGN_CENTER_HORIZONTAL
)
841 pt
.x
= x
+ (w
- sz
.x
) / 2;
843 else if (flag
& wxALIGN_RIGHT
)
845 pt
.x
= x
+ (w
- sz
.x
);
848 if (flag
& wxALIGN_CENTER_VERTICAL
)
850 pt
.y
= y
+ (h
- sz
.y
) / 2;
852 else if (flag
& wxALIGN_BOTTOM
)
854 pt
.y
= y
+ (h
- sz
.y
);
858 item
->SetDimension(pt
, sz
);
861 //---------------------------------------------------------------------------
863 //---------------------------------------------------------------------------
865 wxFlexGridSizer::wxFlexGridSizer( int rows
, int cols
, int vgap
, int hgap
)
866 : wxGridSizer( rows
, cols
, vgap
, hgap
)
868 m_rowHeights
= (int*) NULL
;
869 m_colWidths
= (int*) NULL
;
872 wxFlexGridSizer::wxFlexGridSizer( int cols
, int vgap
, int hgap
)
873 : wxGridSizer( cols
, vgap
, hgap
)
875 m_rowHeights
= (int*) NULL
;
876 m_colWidths
= (int*) NULL
;
879 wxFlexGridSizer::~wxFlexGridSizer()
882 delete[] m_rowHeights
;
884 delete[] m_colWidths
;
887 void wxFlexGridSizer::CreateArrays()
890 delete[] m_rowHeights
;
892 delete[] m_colWidths
;
894 int nitems
, nrows
, ncols
;
895 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
901 m_rowHeights
= new int[nrows
];
902 m_colWidths
= new int[ncols
];
904 for (int col
= 0; col
< ncols
; col
++)
905 m_colWidths
[ col
] = 0;
906 for (int row
= 0; row
< nrows
; row
++)
907 m_rowHeights
[ row
] = 0;
910 void wxFlexGridSizer::RecalcSizes()
912 int nitems
, nrows
, ncols
;
913 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
916 wxSize
sz( GetSize() );
917 wxSize
minsz( CalcMin() );
918 wxPoint
pt( GetPosition() );
923 // Transfer only those rows into temp which exist in the sizer
924 // ignoring the superflouus ones. This prevents a segfault when
925 // calling AddGrowableRow( 3 ) if the sizer only has 2 rows.
926 for (idx
= 0; idx
< m_growableRows
.GetCount(); idx
++)
927 if (m_growableRows
[idx
] < nrows
)
928 temp
.Add( m_growableRows
[idx
] );
929 num
= temp
.GetCount();
931 if ((num
> 0) && (sz
.y
> minsz
.y
))
933 delta
= (sz
.y
- minsz
.y
) / num
;
934 for (idx
= 0; idx
< num
; idx
++)
935 m_rowHeights
[ temp
[idx
] ] += delta
;
940 for (idx
= 0; idx
< m_growableCols
.GetCount(); idx
++)
941 if (m_growableCols
[idx
] < ncols
)
942 temp
.Add( m_growableCols
[idx
] );
943 num
= temp
.GetCount();
945 if ((num
> 0) && (sz
.x
> minsz
.x
))
947 delta
= (sz
.x
- minsz
.x
) / num
;
948 for (idx
= 0; idx
< num
; idx
++)
949 m_colWidths
[ temp
[idx
] ] += delta
;
952 sz
= wxSize( pt
.x
+ sz
.x
, pt
.y
+ sz
.y
);
955 for (int c
= 0; c
< ncols
; c
++)
958 for (int r
= 0; r
< nrows
; r
++)
960 int i
= r
* ncols
+ c
;
963 wxNode
*node
= m_children
.Nth( i
);
966 int w
= wxMax( 0, wxMin( m_colWidths
[c
], sz
.x
- x
) );
967 int h
= wxMax( 0, wxMin( m_rowHeights
[r
], sz
.y
- y
) );
969 SetItemBounds( (wxSizerItem
*) node
->Data(), x
, y
, w
, h
);
971 y
= y
+ m_rowHeights
[r
] + m_vgap
;
973 x
= x
+ m_colWidths
[c
] + m_hgap
;
977 wxSize
wxFlexGridSizer::CalcMin()
979 int nitems
, nrows
, ncols
;
980 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
981 return wxSize(10,10);
986 wxNode
*node
= m_children
.First();
989 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
990 wxSize
sz( item
->CalcMin() );
993 m_rowHeights
[ row
] = wxMax( sz
.y
, m_rowHeights
[ row
] );
994 m_colWidths
[ col
] = wxMax( sz
.x
, m_colWidths
[ col
] );
1001 for (int col
= 0; col
< ncols
; col
++)
1002 width
+= m_colWidths
[ col
];
1005 for (int row
= 0; row
< nrows
; row
++)
1006 height
+= m_rowHeights
[ row
];
1008 return wxSize( width
+ (ncols
-1) * m_hgap
,
1009 height
+ (nrows
-1) * m_vgap
);
1012 void wxFlexGridSizer::AddGrowableRow( size_t idx
)
1014 m_growableRows
.Add( idx
);
1017 void wxFlexGridSizer::RemoveGrowableRow( size_t WXUNUSED(idx
) )
1021 void wxFlexGridSizer::AddGrowableCol( size_t idx
)
1023 m_growableCols
.Add( idx
);
1026 void wxFlexGridSizer::RemoveGrowableCol( size_t WXUNUSED(idx
) )
1030 //---------------------------------------------------------------------------
1032 //---------------------------------------------------------------------------
1034 wxBoxSizer::wxBoxSizer( int orient
)
1039 void wxBoxSizer::RecalcSizes()
1041 if (m_children
.GetCount() == 0)
1048 if (m_orient
== wxHORIZONTAL
)
1050 delta
= (m_size
.x
- m_fixedWidth
) / m_stretchable
;
1051 extra
= (m_size
.x
- m_fixedWidth
) % m_stretchable
;
1055 delta
= (m_size
.y
- m_fixedHeight
) / m_stretchable
;
1056 extra
= (m_size
.y
- m_fixedHeight
) % m_stretchable
;
1060 wxPoint
pt( m_position
);
1062 wxNode
*node
= m_children
.GetFirst();
1065 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
1066 if (item
->IsShown())
1069 if (item
->GetOption())
1070 weight
= item
->GetOption();
1072 wxSize
size( item
->CalcMin() );
1074 if (m_orient
== wxVERTICAL
)
1076 wxCoord height
= size
.y
;
1077 if (item
->GetOption())
1079 height
= (delta
* weight
) + extra
;
1080 extra
= 0; // only the first item will get the remainder as extra size
1083 wxPoint
child_pos( pt
);
1084 wxSize
child_size( wxSize( size
.x
, height
) );
1086 if (item
->GetFlag() & (wxEXPAND
| wxSHAPED
))
1087 child_size
.x
= m_size
.x
;
1088 else if (item
->GetFlag() & wxALIGN_RIGHT
)
1089 child_pos
.x
+= m_size
.x
- size
.x
;
1090 else if (item
->GetFlag() & (wxCENTER
| wxALIGN_CENTER_HORIZONTAL
))
1091 // XXX wxCENTER is added for backward compatibility;
1092 // wxALIGN_CENTER should be used in new code
1093 child_pos
.x
+= (m_size
.x
- size
.x
) / 2;
1095 item
->SetDimension( child_pos
, child_size
);
1101 wxCoord width
= size
.x
;
1102 if (item
->GetOption())
1104 width
= (delta
* weight
) + extra
;
1105 extra
= 0; // only the first item will get the remainder as extra size
1108 wxPoint
child_pos( pt
);
1109 wxSize
child_size( wxSize(width
, size
.y
) );
1111 if (item
->GetFlag() & (wxEXPAND
| wxSHAPED
))
1112 child_size
.y
= m_size
.y
;
1113 else if (item
->GetFlag() & wxALIGN_BOTTOM
)
1114 child_pos
.y
+= m_size
.y
- size
.y
;
1115 else if (item
->GetFlag() & (wxCENTER
| wxALIGN_CENTER_VERTICAL
))
1116 // XXX wxCENTER is added for backward compatibility;
1117 // wxALIGN_CENTER should be used in new code
1118 child_pos
.y
+= (m_size
.y
- size
.y
) / 2;
1120 item
->SetDimension( child_pos
, child_size
);
1126 node
= node
->Next();
1130 wxSize
wxBoxSizer::CalcMin()
1132 if (m_children
.GetCount() == 0)
1133 return wxSize(10,10);
1141 // Find how long each stretch unit needs to be
1142 int stretchSize
= 1;
1143 wxNode
*node
= m_children
.GetFirst();
1146 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
1147 if (item
->IsShown() && item
->GetOption() != 0)
1149 int stretch
= item
->GetOption();
1150 wxSize
size( item
->CalcMin() );
1152 // Integer division rounded up is (a + b - 1) / b
1153 if (m_orient
== wxHORIZONTAL
)
1154 sizePerStretch
= ( size
.x
+ stretch
- 1 ) / stretch
;
1156 sizePerStretch
= ( size
.y
+ stretch
- 1 ) / stretch
;
1157 if (sizePerStretch
> stretchSize
)
1158 stretchSize
= sizePerStretch
;
1160 node
= node
->Next();
1162 // Calculate overall minimum size
1163 node
= m_children
.GetFirst();
1166 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
1167 if (item
->IsShown())
1169 m_stretchable
+= item
->GetOption();
1171 wxSize
size( item
->CalcMin() );
1172 if (item
->GetOption() != 0)
1174 if (m_orient
== wxHORIZONTAL
)
1175 size
.x
= stretchSize
* item
->GetOption();
1177 size
.y
= stretchSize
* item
->GetOption();
1180 if (m_orient
== wxHORIZONTAL
)
1182 m_minWidth
+= size
.x
;
1183 m_minHeight
= wxMax( m_minHeight
, size
.y
);
1187 m_minHeight
+= size
.y
;
1188 m_minWidth
= wxMax( m_minWidth
, size
.x
);
1191 if (item
->GetOption() == 0)
1193 if (m_orient
== wxVERTICAL
)
1195 m_fixedHeight
+= size
.y
;
1196 m_fixedWidth
= wxMax( m_fixedWidth
, size
.x
);
1200 m_fixedWidth
+= size
.x
;
1201 m_fixedHeight
= wxMax( m_fixedHeight
, size
.y
);
1205 node
= node
->Next();
1208 return wxSize( m_minWidth
, m_minHeight
);
1211 //---------------------------------------------------------------------------
1213 //---------------------------------------------------------------------------
1217 wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox
*box
, int orient
)
1218 : wxBoxSizer( orient
)
1220 wxASSERT_MSG( box
, wxT("wxStaticBoxSizer needs a static box") );
1225 static void GetStaticBoxBorders(wxStaticBox
*box
,
1226 int *borderTop
, int *borderOther
)
1228 // this has to be done platform by platform as there is no way to
1229 // guess the thickness of a wxStaticBox border
1231 if ( box
->GetLabel().IsEmpty() )
1240 void wxStaticBoxSizer::RecalcSizes()
1242 int top_border
, other_border
;
1243 GetStaticBoxBorders(m_staticBox
, &top_border
, &other_border
);
1245 m_staticBox
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y
);
1247 wxPoint
old_pos( m_position
);
1248 m_position
.x
+= other_border
;
1249 m_position
.y
+= top_border
;
1250 wxSize
old_size( m_size
);
1251 m_size
.x
-= 2*other_border
;
1252 m_size
.y
-= top_border
+ other_border
;
1254 wxBoxSizer::RecalcSizes();
1256 m_position
= old_pos
;
1260 wxSize
wxStaticBoxSizer::CalcMin()
1262 int top_border
, other_border
;
1263 GetStaticBoxBorders(m_staticBox
, &top_border
, &other_border
);
1265 wxSize
ret( wxBoxSizer::CalcMin() );
1266 ret
.x
+= 2*other_border
;
1267 ret
.y
+= other_border
+ top_border
;
1272 #endif // wxUSE_STATBOX
1274 //---------------------------------------------------------------------------
1276 //---------------------------------------------------------------------------
1280 wxNotebookSizer::wxNotebookSizer( wxNotebook
*nb
)
1282 wxASSERT_MSG( nb
, wxT("wxNotebookSizer needs a notebook") );
1287 void wxNotebookSizer::RecalcSizes()
1289 m_notebook
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y
);
1292 wxSize
wxNotebookSizer::CalcMin()
1294 wxSize sizeBorder
= m_notebook
->CalcSizeFromPage(wxSize(0, 0));
1299 if (m_notebook
->GetChildren().GetCount() == 0)
1301 return wxSize(sizeBorder
.x
+ 10, sizeBorder
.y
+ 10);
1307 wxWindowList::Node
*node
= m_notebook
->GetChildren().GetFirst();
1310 wxWindow
*item
= node
->GetData();
1311 wxSizer
*itemsizer
= item
->GetSizer();
1315 wxSize
subsize( itemsizer
->CalcMin() );
1317 if (subsize
.x
> maxX
)
1319 if (subsize
.y
> maxY
)
1323 node
= node
->GetNext();
1326 return wxSize( maxX
, maxY
) + sizeBorder
;
1329 #endif // wxUSE_NOTEBOOK