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
)
49 , m_size( wxSize( width
, height
) ) // size is set directly
50 , m_minSize( m_size
) // minimal size is the initial size
54 , m_show( TRUE
) // Cannot be changed
55 , m_deleteItem( FALSE
) // unused for spacer
56 , m_userData( userData
)
61 wxSizerItem::wxSizerItem( wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
64 , m_minSize( window
->GetSize() ) // minimal size is the initial size
69 , m_deleteItem( FALSE
) // currently unused for window
70 , m_userData( userData
)
72 // aspect ratio calculated from initial size
73 SetRatio( m_minSize
);
75 // m_size is calculated later
78 wxSizerItem::wxSizerItem( wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
86 , m_deleteItem( TRUE
) // we delete sizer items by default.
87 , m_userData( userData
)
89 // m_minSize is calculated later
90 // m_size is calculated later
93 wxSizerItem::~wxSizerItem()
95 // User data is bound to the sizeritem, always delete it.
99 // To be able to Detach a sizer, we must be able to veto its deletion here.
100 if (m_deleteItem
&& m_sizer
)
105 wxSize
wxSizerItem::GetSize()
109 ret
= m_sizer
->GetSize();
112 ret
= m_window
->GetSize();
119 if (m_flag
& wxNORTH
)
121 if (m_flag
& wxSOUTH
)
127 wxSize
wxSizerItem::CalcMin()
132 ret
= m_sizer
->GetMinSize();
134 // if we have to preserve aspect ratio _AND_ this is
135 // the first-time calculation, consider ret to be initial size
136 if ((m_flag
& wxSHAPED
) && !m_ratio
)
141 if ( IsWindow() && (m_flag
& wxADJUST_MINSIZE
) )
143 // By user request, keep the minimal size for this item
144 // in sync with the largest of BestSize and any user supplied
145 // minimum size hint. Useful in cases where the item is
146 // changeable -- static text labels, etc.
147 m_minSize
= m_window
->GetAdjustedBestSize();
157 if (m_flag
& wxNORTH
)
159 if (m_flag
& wxSOUTH
)
165 void wxSizerItem::SetDimension( wxPoint pos
, wxSize size
)
167 if (m_flag
& wxSHAPED
)
169 // adjust aspect ratio
170 int rwidth
= (int) (size
.y
* m_ratio
);
174 int rheight
= (int) (size
.x
/ m_ratio
);
175 // add vertical space
176 if (m_flag
& wxALIGN_CENTER_VERTICAL
)
177 pos
.y
+= (size
.y
- rheight
) / 2;
178 else if (m_flag
& wxALIGN_BOTTOM
)
179 pos
.y
+= (size
.y
- rheight
);
180 // use reduced dimensions
183 else if (rwidth
< size
.x
)
185 // add horizontal space
186 if (m_flag
& wxALIGN_CENTER_HORIZONTAL
)
187 pos
.x
+= (size
.x
- rwidth
) / 2;
188 else if (m_flag
& wxALIGN_RIGHT
)
189 pos
.x
+= (size
.x
- rwidth
);
194 // This is what GetPosition() returns. Since we calculate
195 // borders afterwards, GetPosition() will be the left/top
196 // corner of the surrounding border.
208 if (m_flag
& wxNORTH
)
213 if (m_flag
& wxSOUTH
)
219 m_sizer
->SetDimension( pos
.x
, pos
.y
, size
.x
, size
.y
);
222 m_window
->SetSize( pos
.x
, pos
.y
, size
.x
, size
.y
, wxSIZE_ALLOW_MINUS_ONE
);
227 void wxSizerItem::DeleteWindows()
233 m_sizer
->DeleteWindows();
236 bool wxSizerItem::IsWindow()
238 return (m_window
!= NULL
);
241 bool wxSizerItem::IsSizer()
243 return (m_sizer
!= NULL
);
246 bool wxSizerItem::IsSpacer()
248 return (m_window
== NULL
) && (m_sizer
== NULL
);
251 //---------------------------------------------------------------------------
253 //---------------------------------------------------------------------------
257 m_children
.DeleteContents( TRUE
);
267 void wxSizer::Add( wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
269 m_children
.Append( new wxSizerItem( window
, option
, flag
, border
, userData
) );
270 window
->SetContainingSizer(this);
273 void wxSizer::Add( wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
275 m_children
.Append( new wxSizerItem( sizer
, option
, flag
, border
, userData
) );
278 void wxSizer::Add( int width
, int height
, int option
, int flag
, int border
, wxObject
* userData
)
280 m_children
.Append( new wxSizerItem( width
, height
, option
, flag
, border
, userData
) );
283 void wxSizer::Prepend( wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
285 m_children
.Insert( new wxSizerItem( window
, option
, flag
, border
, userData
) );
286 window
->SetContainingSizer(this);
289 void wxSizer::Prepend( wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
291 m_children
.Insert( new wxSizerItem( sizer
, option
, flag
, border
, userData
) );
294 void wxSizer::Prepend( int width
, int height
, int option
, int flag
, int border
, wxObject
* userData
)
296 m_children
.Insert( new wxSizerItem( width
, height
, option
, flag
, border
, userData
) );
299 void wxSizer::Insert( int before
, wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
301 m_children
.Insert( before
, new wxSizerItem( window
, option
, flag
, border
, userData
) );
302 window
->SetContainingSizer(this);
305 void wxSizer::Insert( int before
, wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
307 m_children
.Insert( before
, new wxSizerItem( sizer
, option
, flag
, border
, userData
) );
310 void wxSizer::Insert( int before
, int width
, int height
, int option
, int flag
, int border
, wxObject
* userData
)
312 m_children
.Insert( before
, new wxSizerItem( width
, height
, option
, flag
, border
, userData
) );
315 bool wxSizer::Remove( wxWindow
*window
)
319 wxNode
*node
= m_children
.First();
322 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
323 if (item
->GetWindow() == window
)
325 item
->GetWindow()->SetContainingSizer(NULL
);
326 m_children
.DeleteNode( node
);
335 bool wxSizer::Remove( wxSizer
*sizer
)
339 wxNode
*node
= m_children
.First();
342 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
343 if (item
->GetSizer() == sizer
)
345 m_children
.DeleteNode( node
);
354 bool wxSizer::Remove( int pos
)
356 if ((size_t)pos
>= m_children
.GetCount())
358 wxNode
*node
= m_children
.Nth( pos
);
359 if (!node
) return FALSE
;
361 m_children
.DeleteNode( node
);
366 bool wxSizer::Detach( wxSizer
*sizer
)
370 wxNode
*node
= m_children
.First();
373 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
374 if (item
->GetSizer() == sizer
)
376 item
->SetDeleteItem( FALSE
);
377 m_children
.DeleteNode( node
);
386 bool wxSizer::Detach( int pos
)
388 if ((size_t)pos
>= m_children
.GetCount())
390 wxNode
*node
= m_children
.Nth( pos
);
391 if (!node
) return FALSE
;
393 ( (wxSizerItem
*)node
->Data() )->SetDeleteItem( FALSE
);
394 m_children
.DeleteNode( node
);
399 void wxSizer::Clear( bool delete_windows
)
401 // First clear the ContainingSizer pointers
402 wxNode
*node
= m_children
.First();
405 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
406 if (item
->IsWindow())
407 item
->GetWindow()->SetContainingSizer(NULL
);
411 // Destroy the windows if needed
415 // Now empty the list
419 void wxSizer::DeleteWindows()
421 wxNode
*node
= m_children
.First();
424 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
425 item
->DeleteWindows();
430 wxSize
wxSizer::Fit( wxWindow
*window
)
433 if (window
->IsTopLevel())
434 size
= FitSize( window
);
436 size
= GetMinWindowSize( window
);
438 window
->SetSize( size
);
443 void wxSizer::FitInside( wxWindow
*window
)
446 if (window
->IsTopLevel())
447 size
= VirtualFitSize( window
);
449 size
= GetMinClientSize( window
);
451 window
->SetVirtualSize( size
);
454 void wxSizer::Layout()
460 void wxSizer::SetSizeHints( wxWindow
*window
)
462 // Preserve the window's max size hints, but set the
463 // lower bound according to the sizer calculations.
465 wxSize size
= Fit( window
);
467 window
->SetSizeHints( size
.x
,
469 window
->GetMaxWidth(),
470 window
->GetMaxHeight() );
473 void wxSizer::SetVirtualSizeHints( wxWindow
*window
)
475 // Preserve the window's max size hints, but set the
476 // lower bound according to the sizer calculations.
479 wxSize
size( window
->GetVirtualSize() );
480 window
->SetVirtualSizeHints( size
.x
,
482 window
->GetMaxWidth(),
483 window
->GetMaxHeight() );
486 wxSize
wxSizer::GetMaxWindowSize( wxWindow
*window
)
488 return window
->GetMaxSize();
491 wxSize
wxSizer::GetMinWindowSize( wxWindow
*window
)
493 wxSize
minSize( GetMinSize() );
494 wxSize
size( window
->GetSize() );
495 wxSize
client_size( window
->GetClientSize() );
496 return wxSize( minSize
.x
+size
.x
-client_size
.x
,
497 minSize
.y
+size
.y
-client_size
.y
);
500 // Return a window size that will fit within the screens dimensions
501 wxSize
wxSizer::FitSize( wxWindow
*window
)
503 wxSize size
= GetMinWindowSize( window
);
504 wxSize sizeMax
= GetMaxWindowSize( window
);
506 // Limit the size if sizeMax != wxDefaultSize
508 if ( size
.x
> sizeMax
.x
&& sizeMax
.x
!= -1 )
510 if ( size
.y
> sizeMax
.y
&& sizeMax
.y
!= -1 )
516 wxSize
wxSizer::GetMaxClientSize( wxWindow
*window
)
518 wxSize
maxSize( window
->GetMaxSize() );
520 if( maxSize
!= wxDefaultSize
)
522 wxSize
size( window
->GetSize() );
523 wxSize
client_size( window
->GetClientSize() );
525 return wxSize( maxSize
.x
+ client_size
.x
- size
.x
,
526 maxSize
.y
+ client_size
.y
- size
.y
);
529 return wxDefaultSize
;
532 wxSize
wxSizer::GetMinClientSize( wxWindow
*WXUNUSED(window
) )
534 return GetMinSize(); // Already returns client size.
537 wxSize
wxSizer::VirtualFitSize( wxWindow
*window
)
539 wxSize size
= GetMinClientSize( window
);
540 wxSize sizeMax
= GetMaxClientSize( window
);
542 // Limit the size if sizeMax != wxDefaultSize
544 if ( size
.x
> sizeMax
.x
&& sizeMax
.x
!= -1 )
546 if ( size
.y
> sizeMax
.y
&& sizeMax
.y
!= -1 )
552 void wxSizer::SetDimension( int x
, int y
, int width
, int height
)
561 wxSize
wxSizer::GetMinSize()
563 wxSize
ret( CalcMin() );
564 if (ret
.x
< m_minSize
.x
) ret
.x
= m_minSize
.x
;
565 if (ret
.y
< m_minSize
.y
) ret
.y
= m_minSize
.y
;
569 void wxSizer::DoSetMinSize( int width
, int height
)
572 m_minSize
.y
= height
;
575 bool wxSizer::DoSetItemMinSize( wxWindow
*window
, int width
, int height
)
579 wxNode
*node
= m_children
.First();
582 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
583 if (item
->GetWindow() == window
)
585 item
->SetInitSize( width
, height
);
591 node
= m_children
.First();
594 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
595 if (item
->GetSizer())
597 // It's a sizer, so lets search recursively.
598 if (item
->GetSizer()->DoSetItemMinSize( window
, width
, height
))
600 // A child sizer found the requested windw, exit.
610 bool wxSizer::DoSetItemMinSize( wxSizer
*sizer
, int width
, int height
)
614 wxNode
*node
= m_children
.First();
617 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
618 if (item
->GetSizer() == sizer
)
620 item
->GetSizer()->DoSetMinSize( width
, height
);
626 node
= m_children
.First();
629 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
630 if (item
->GetSizer())
632 // It's a sizer, so lets search recursively.
633 if (item
->GetSizer()->DoSetItemMinSize( sizer
, width
, height
))
635 // A child sizer found the requested windw, exit.
645 bool wxSizer::DoSetItemMinSize( int pos
, int width
, int height
)
647 wxNode
*node
= m_children
.Nth( pos
);
648 if (!node
) return FALSE
;
650 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
651 if (item
->GetSizer())
653 // Sizers contains the minimal size in them, if not calculated ...
654 item
->GetSizer()->DoSetMinSize( width
, height
);
658 // ... but the minimal size of spacers and windows in stored in them
659 item
->SetInitSize( width
, height
);
665 void wxSizer::Show(wxWindow
*window
, bool show
)
667 wxNode
*node
= m_children
.GetFirst();
670 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
672 if (item
->IsWindow() && item
->GetWindow() == window
)
682 void wxSizer::Show(wxSizer
*sizer
, bool show
)
684 wxNode
*node
= m_children
.GetFirst();
687 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
689 if (item
->IsSizer() && item
->GetSizer() == sizer
)
692 sizer
->ShowItems(show
);
699 void wxSizer::ShowItems (bool show
)
701 wxNode
*node
= m_children
.GetFirst();
704 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
706 if (item
->IsWindow())
707 item
->GetWindow()->Show (show
);
708 else if (item
->IsSizer())
709 item
->GetSizer()->ShowItems (show
);
715 bool wxSizer::IsShown (wxWindow
*window
)
717 wxNode
*node
= m_children
.GetFirst();
720 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
722 if (item
->IsWindow() && item
->GetWindow() == window
)
724 return item
->IsShown();
732 bool wxSizer::IsShown (wxSizer
*sizer
)
734 wxNode
*node
= m_children
.GetFirst();
737 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
739 if (item
->IsSizer() && item
->GetSizer() == sizer
)
741 return item
->IsShown();
749 //---------------------------------------------------------------------------
751 //---------------------------------------------------------------------------
753 wxGridSizer::wxGridSizer( int rows
, int cols
, int vgap
, int hgap
)
761 wxGridSizer::wxGridSizer( int cols
, int vgap
, int hgap
)
769 int wxGridSizer::CalcRowsCols(int& nrows
, int& ncols
) const
771 int nitems
= m_children
.GetCount();
777 nrows
= (nitems
+ m_cols
- 1) / m_cols
;
781 ncols
= (nitems
+ m_rows
- 1) / m_rows
;
784 else // 0 columns, 0 rows?
786 wxFAIL_MSG( _T("grid sizer must have either rows or columns fixed") );
795 void wxGridSizer::RecalcSizes()
797 int nitems
, nrows
, ncols
;
798 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
801 wxSize
sz( GetSize() );
802 wxPoint
pt( GetPosition() );
804 int w
= (sz
.x
- (ncols
- 1) * m_hgap
) / ncols
;
805 int h
= (sz
.y
- (nrows
- 1) * m_vgap
) / nrows
;
808 for (int c
= 0; c
< ncols
; c
++)
811 for (int r
= 0; r
< nrows
; r
++)
813 int i
= r
* ncols
+ c
;
816 wxNode
*node
= m_children
.Nth( i
);
819 SetItemBounds( (wxSizerItem
*) node
->Data(), x
, y
, w
, h
);
827 wxSize
wxGridSizer::CalcMin()
829 int nitems
, nrows
, ncols
;
830 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
831 return wxSize(10, 10);
833 // Find the max width and height for any component
837 wxNode
*node
= m_children
.First();
840 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
841 wxSize
sz( item
->CalcMin() );
842 w
= wxMax( w
, sz
.x
);
843 h
= wxMax( h
, sz
.y
);
848 return wxSize(ncols
* w
+ (ncols
-1) * m_hgap
,
849 nrows
* h
+ (nrows
-1) * m_vgap
);
852 void wxGridSizer::SetItemBounds( wxSizerItem
*item
, int x
, int y
, int w
, int h
)
855 wxSize
sz( item
->CalcMin() );
856 int flag
= item
->GetFlag();
858 if ((flag
& wxEXPAND
) || (flag
& wxSHAPED
))
864 if (flag
& wxALIGN_CENTER_HORIZONTAL
)
866 pt
.x
= x
+ (w
- sz
.x
) / 2;
868 else if (flag
& wxALIGN_RIGHT
)
870 pt
.x
= x
+ (w
- sz
.x
);
873 if (flag
& wxALIGN_CENTER_VERTICAL
)
875 pt
.y
= y
+ (h
- sz
.y
) / 2;
877 else if (flag
& wxALIGN_BOTTOM
)
879 pt
.y
= y
+ (h
- sz
.y
);
883 item
->SetDimension(pt
, sz
);
886 //---------------------------------------------------------------------------
888 //---------------------------------------------------------------------------
890 wxFlexGridSizer::wxFlexGridSizer( int rows
, int cols
, int vgap
, int hgap
)
891 : wxGridSizer( rows
, cols
, vgap
, hgap
)
893 m_rowHeights
= (int*) NULL
;
894 m_colWidths
= (int*) NULL
;
897 wxFlexGridSizer::wxFlexGridSizer( int cols
, int vgap
, int hgap
)
898 : wxGridSizer( cols
, vgap
, hgap
)
900 m_rowHeights
= (int*) NULL
;
901 m_colWidths
= (int*) NULL
;
904 wxFlexGridSizer::~wxFlexGridSizer()
907 delete[] m_rowHeights
;
909 delete[] m_colWidths
;
912 void wxFlexGridSizer::CreateArrays()
915 delete[] m_rowHeights
;
917 delete[] m_colWidths
;
919 int nitems
, nrows
, ncols
;
920 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
926 m_rowHeights
= new int[nrows
];
927 m_colWidths
= new int[ncols
];
929 for (int col
= 0; col
< ncols
; col
++)
930 m_colWidths
[ col
] = 0;
931 for (int row
= 0; row
< nrows
; row
++)
932 m_rowHeights
[ row
] = 0;
935 void wxFlexGridSizer::RecalcSizes()
937 int nitems
, nrows
, ncols
;
938 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
941 wxSize
sz( GetSize() );
942 wxSize
minsz( CalcMin() );
943 wxPoint
pt( GetPosition() );
948 // Transfer only those rows into temp which exist in the sizer
949 // ignoring the superflouus ones. This prevents a segfault when
950 // calling AddGrowableRow( 3 ) if the sizer only has 2 rows.
951 for (idx
= 0; idx
< m_growableRows
.GetCount(); idx
++)
952 if (m_growableRows
[idx
] < nrows
)
953 temp
.Add( m_growableRows
[idx
] );
954 num
= temp
.GetCount();
956 if ((num
> 0) && (sz
.y
> minsz
.y
))
958 delta
= (sz
.y
- minsz
.y
) / num
;
959 for (idx
= 0; idx
< num
; idx
++)
960 m_rowHeights
[ temp
[idx
] ] += delta
;
965 for (idx
= 0; idx
< m_growableCols
.GetCount(); idx
++)
966 if (m_growableCols
[idx
] < ncols
)
967 temp
.Add( m_growableCols
[idx
] );
968 num
= temp
.GetCount();
970 if ((num
> 0) && (sz
.x
> minsz
.x
))
972 delta
= (sz
.x
- minsz
.x
) / num
;
973 for (idx
= 0; idx
< num
; idx
++)
974 m_colWidths
[ temp
[idx
] ] += delta
;
977 sz
= wxSize( pt
.x
+ sz
.x
, pt
.y
+ sz
.y
);
980 for (int c
= 0; c
< ncols
; c
++)
983 for (int r
= 0; r
< nrows
; r
++)
985 int i
= r
* ncols
+ c
;
988 wxNode
*node
= m_children
.Nth( i
);
991 int w
= wxMax( 0, wxMin( m_colWidths
[c
], sz
.x
- x
) );
992 int h
= wxMax( 0, wxMin( m_rowHeights
[r
], sz
.y
- y
) );
994 SetItemBounds( (wxSizerItem
*) node
->Data(), x
, y
, w
, h
);
996 y
= y
+ m_rowHeights
[r
] + m_vgap
;
998 x
= x
+ m_colWidths
[c
] + m_hgap
;
1002 wxSize
wxFlexGridSizer::CalcMin()
1004 int nitems
, nrows
, ncols
;
1005 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
1006 return wxSize(10,10);
1011 wxNode
*node
= m_children
.First();
1014 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
1015 wxSize
sz( item
->CalcMin() );
1016 int row
= i
/ ncols
;
1017 int col
= i
% ncols
;
1018 m_rowHeights
[ row
] = wxMax( sz
.y
, m_rowHeights
[ row
] );
1019 m_colWidths
[ col
] = wxMax( sz
.x
, m_colWidths
[ col
] );
1021 node
= node
->Next();
1026 for (int col
= 0; col
< ncols
; col
++)
1027 width
+= m_colWidths
[ col
];
1030 for (int row
= 0; row
< nrows
; row
++)
1031 height
+= m_rowHeights
[ row
];
1033 return wxSize( width
+ (ncols
-1) * m_hgap
,
1034 height
+ (nrows
-1) * m_vgap
);
1037 void wxFlexGridSizer::AddGrowableRow( size_t idx
)
1039 m_growableRows
.Add( idx
);
1042 void wxFlexGridSizer::RemoveGrowableRow( size_t WXUNUSED(idx
) )
1046 void wxFlexGridSizer::AddGrowableCol( size_t idx
)
1048 m_growableCols
.Add( idx
);
1051 void wxFlexGridSizer::RemoveGrowableCol( size_t WXUNUSED(idx
) )
1055 //---------------------------------------------------------------------------
1057 //---------------------------------------------------------------------------
1059 wxBoxSizer::wxBoxSizer( int orient
)
1064 void wxBoxSizer::RecalcSizes()
1066 if (m_children
.GetCount() == 0)
1073 if (m_orient
== wxHORIZONTAL
)
1075 delta
= (m_size
.x
- m_fixedWidth
) / m_stretchable
;
1076 extra
= (m_size
.x
- m_fixedWidth
) % m_stretchable
;
1080 delta
= (m_size
.y
- m_fixedHeight
) / m_stretchable
;
1081 extra
= (m_size
.y
- m_fixedHeight
) % m_stretchable
;
1085 wxPoint
pt( m_position
);
1087 wxNode
*node
= m_children
.GetFirst();
1090 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
1091 if (item
->IsShown())
1094 if (item
->GetOption())
1095 weight
= item
->GetOption();
1097 wxSize
size( item
->CalcMin() );
1099 if (m_orient
== wxVERTICAL
)
1101 wxCoord height
= size
.y
;
1102 if (item
->GetOption())
1104 height
= (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( size
.x
, height
) );
1111 if (item
->GetFlag() & (wxEXPAND
| wxSHAPED
))
1112 child_size
.x
= m_size
.x
;
1113 else if (item
->GetFlag() & wxALIGN_RIGHT
)
1114 child_pos
.x
+= m_size
.x
- size
.x
;
1115 else if (item
->GetFlag() & (wxCENTER
| wxALIGN_CENTER_HORIZONTAL
))
1116 // XXX wxCENTER is added for backward compatibility;
1117 // wxALIGN_CENTER should be used in new code
1118 child_pos
.x
+= (m_size
.x
- size
.x
) / 2;
1120 item
->SetDimension( child_pos
, child_size
);
1126 wxCoord width
= size
.x
;
1127 if (item
->GetOption())
1129 width
= (delta
* weight
) + extra
;
1130 extra
= 0; // only the first item will get the remainder as extra size
1133 wxPoint
child_pos( pt
);
1134 wxSize
child_size( wxSize(width
, size
.y
) );
1136 if (item
->GetFlag() & (wxEXPAND
| wxSHAPED
))
1137 child_size
.y
= m_size
.y
;
1138 else if (item
->GetFlag() & wxALIGN_BOTTOM
)
1139 child_pos
.y
+= m_size
.y
- size
.y
;
1140 else if (item
->GetFlag() & (wxCENTER
| wxALIGN_CENTER_VERTICAL
))
1141 // XXX wxCENTER is added for backward compatibility;
1142 // wxALIGN_CENTER should be used in new code
1143 child_pos
.y
+= (m_size
.y
- size
.y
) / 2;
1145 item
->SetDimension( child_pos
, child_size
);
1151 node
= node
->Next();
1155 wxSize
wxBoxSizer::CalcMin()
1157 if (m_children
.GetCount() == 0)
1158 return wxSize(10,10);
1166 // Find how long each stretch unit needs to be
1167 int stretchSize
= 1;
1168 wxNode
*node
= m_children
.GetFirst();
1171 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
1172 if (item
->IsShown() && item
->GetOption() != 0)
1174 int stretch
= item
->GetOption();
1175 wxSize
size( item
->CalcMin() );
1177 // Integer division rounded up is (a + b - 1) / b
1178 if (m_orient
== wxHORIZONTAL
)
1179 sizePerStretch
= ( size
.x
+ stretch
- 1 ) / stretch
;
1181 sizePerStretch
= ( size
.y
+ stretch
- 1 ) / stretch
;
1182 if (sizePerStretch
> stretchSize
)
1183 stretchSize
= sizePerStretch
;
1185 node
= node
->Next();
1187 // Calculate overall minimum size
1188 node
= m_children
.GetFirst();
1191 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
1192 if (item
->IsShown())
1194 m_stretchable
+= item
->GetOption();
1196 wxSize
size( item
->CalcMin() );
1197 if (item
->GetOption() != 0)
1199 if (m_orient
== wxHORIZONTAL
)
1200 size
.x
= stretchSize
* item
->GetOption();
1202 size
.y
= stretchSize
* item
->GetOption();
1205 if (m_orient
== wxHORIZONTAL
)
1207 m_minWidth
+= size
.x
;
1208 m_minHeight
= wxMax( m_minHeight
, size
.y
);
1212 m_minHeight
+= size
.y
;
1213 m_minWidth
= wxMax( m_minWidth
, size
.x
);
1216 if (item
->GetOption() == 0)
1218 if (m_orient
== wxVERTICAL
)
1220 m_fixedHeight
+= size
.y
;
1221 m_fixedWidth
= wxMax( m_fixedWidth
, size
.x
);
1225 m_fixedWidth
+= size
.x
;
1226 m_fixedHeight
= wxMax( m_fixedHeight
, size
.y
);
1230 node
= node
->Next();
1233 return wxSize( m_minWidth
, m_minHeight
);
1236 //---------------------------------------------------------------------------
1238 //---------------------------------------------------------------------------
1242 wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox
*box
, int orient
)
1243 : wxBoxSizer( orient
)
1245 wxASSERT_MSG( box
, wxT("wxStaticBoxSizer needs a static box") );
1250 static void GetStaticBoxBorders(wxStaticBox
*box
,
1251 int *borderTop
, int *borderOther
)
1253 // this has to be done platform by platform as there is no way to
1254 // guess the thickness of a wxStaticBox border
1256 if ( box
->GetLabel().IsEmpty() )
1265 void wxStaticBoxSizer::RecalcSizes()
1267 int top_border
, other_border
;
1268 GetStaticBoxBorders(m_staticBox
, &top_border
, &other_border
);
1270 m_staticBox
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y
);
1272 wxPoint
old_pos( m_position
);
1273 m_position
.x
+= other_border
;
1274 m_position
.y
+= top_border
;
1275 wxSize
old_size( m_size
);
1276 m_size
.x
-= 2*other_border
;
1277 m_size
.y
-= top_border
+ other_border
;
1279 wxBoxSizer::RecalcSizes();
1281 m_position
= old_pos
;
1285 wxSize
wxStaticBoxSizer::CalcMin()
1287 int top_border
, other_border
;
1288 GetStaticBoxBorders(m_staticBox
, &top_border
, &other_border
);
1290 wxSize
ret( wxBoxSizer::CalcMin() );
1291 ret
.x
+= 2*other_border
;
1292 ret
.y
+= other_border
+ top_border
;
1297 #endif // wxUSE_STATBOX
1299 //---------------------------------------------------------------------------
1301 //---------------------------------------------------------------------------
1305 wxNotebookSizer::wxNotebookSizer( wxNotebook
*nb
)
1307 wxASSERT_MSG( nb
, wxT("wxNotebookSizer needs a notebook") );
1312 void wxNotebookSizer::RecalcSizes()
1314 m_notebook
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y
);
1317 wxSize
wxNotebookSizer::CalcMin()
1319 wxSize sizeBorder
= m_notebook
->CalcSizeFromPage(wxSize(0, 0));
1324 if (m_notebook
->GetChildren().GetCount() == 0)
1326 return wxSize(sizeBorder
.x
+ 10, sizeBorder
.y
+ 10);
1332 wxWindowList::Node
*node
= m_notebook
->GetChildren().GetFirst();
1335 wxWindow
*item
= node
->GetData();
1336 wxSizer
*itemsizer
= item
->GetSizer();
1340 wxSize
subsize( itemsizer
->CalcMin() );
1342 if (subsize
.x
> maxX
)
1344 if (subsize
.y
> maxY
)
1348 node
= node
->GetNext();
1351 return wxSize( maxX
, maxY
) + sizeBorder
;
1354 #endif // wxUSE_NOTEBOOK