1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/sizer.cpp
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 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
23 #include "wx/string.h"
27 #include "wx/settings.h"
28 #include "wx/button.h"
29 #include "wx/statbox.h"
30 #include "wx/toplevel.h"
33 #include "wx/listimpl.cpp"
35 #if WXWIN_COMPATIBILITY_2_4
36 #include "wx/notebook.h"
39 //---------------------------------------------------------------------------
41 IMPLEMENT_CLASS(wxSizerItem
, wxObject
)
42 IMPLEMENT_CLASS(wxSizer
, wxObject
)
43 IMPLEMENT_CLASS(wxGridSizer
, wxSizer
)
44 IMPLEMENT_CLASS(wxFlexGridSizer
, wxGridSizer
)
45 IMPLEMENT_CLASS(wxBoxSizer
, wxSizer
)
47 IMPLEMENT_CLASS(wxStaticBoxSizer
, wxBoxSizer
)
50 IMPLEMENT_CLASS(wxStdDialogButtonSizer
, wxBoxSizer
)
53 WX_DEFINE_EXPORTED_LIST( wxSizerItemList
)
88 // ----------------------------------------------------------------------------
90 // ----------------------------------------------------------------------------
92 void wxSizerItem::Init(const wxSizerFlags
& flags
)
96 m_proportion
= flags
.GetProportion();
97 m_flag
= flags
.GetFlags();
98 m_border
= flags
.GetBorderInPixels();
101 wxSizerItem::wxSizerItem()
113 void wxSizerItem::SetWindow(wxWindow
*window
)
115 wxCHECK_RET( window
, _T("NULL window in wxSizerItem::SetWindow()") );
117 m_kind
= Item_Window
;
120 // window doesn't become smaller than its initial size, whatever happens
121 m_minSize
= window
->GetSize();
123 if ( m_flag
& wxFIXED_MINSIZE
)
124 window
->SetMinSize(m_minSize
);
126 // aspect ratio calculated from initial size
130 wxSizerItem::wxSizerItem(wxWindow
*window
,
135 : m_proportion(proportion
),
144 void wxSizerItem::SetSizer(wxSizer
*sizer
)
150 wxSizerItem::wxSizerItem(wxSizer
*sizer
,
155 : m_proportion(proportion
),
163 // m_minSize is set later
167 void wxSizerItem::SetSpacer(const wxSize
& size
)
169 m_kind
= Item_Spacer
;
170 m_spacer
= new wxSizerSpacer(size
);
175 wxSizerItem::wxSizerItem(int width
,
181 : m_minSize(width
, height
), // minimal size is the initial size
182 m_proportion(proportion
),
187 SetSpacer(width
, height
);
190 wxSizerItem::~wxSizerItem()
200 m_window
->SetContainingSizer(NULL
);
213 wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") );
217 wxSize
wxSizerItem::GetSpacer() const
220 if ( m_kind
== Item_Spacer
)
221 size
= m_spacer
->GetSize();
227 wxSize
wxSizerItem::GetSize() const
236 ret
= m_window
->GetSize();
240 ret
= m_sizer
->GetSize();
244 ret
= m_spacer
->GetSize();
249 wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") );
256 if (m_flag
& wxNORTH
)
258 if (m_flag
& wxSOUTH
)
264 wxSize
wxSizerItem::CalcMin()
268 m_minSize
= m_sizer
->GetMinSize();
270 // if we have to preserve aspect ratio _AND_ this is
271 // the first-time calculation, consider ret to be initial size
272 if ( (m_flag
& wxSHAPED
) && wxIsNullDouble(m_ratio
) )
275 else if ( IsWindow() )
277 // Since the size of the window may change during runtime, we
278 // should use the current minimal/best size.
279 m_minSize
= m_window
->GetBestFittingSize();
282 return GetMinSizeWithBorder();
285 wxSize
wxSizerItem::GetMinSizeWithBorder() const
287 wxSize ret
= m_minSize
;
293 if (m_flag
& wxNORTH
)
295 if (m_flag
& wxSOUTH
)
302 void wxSizerItem::SetDimension( const wxPoint
& pos_
, const wxSize
& size_
)
306 if (m_flag
& wxSHAPED
)
308 // adjust aspect ratio
309 int rwidth
= (int) (size
.y
* m_ratio
);
313 int rheight
= (int) (size
.x
/ m_ratio
);
314 // add vertical space
315 if (m_flag
& wxALIGN_CENTER_VERTICAL
)
316 pos
.y
+= (size
.y
- rheight
) / 2;
317 else if (m_flag
& wxALIGN_BOTTOM
)
318 pos
.y
+= (size
.y
- rheight
);
319 // use reduced dimensions
322 else if (rwidth
< size
.x
)
324 // add horizontal space
325 if (m_flag
& wxALIGN_CENTER_HORIZONTAL
)
326 pos
.x
+= (size
.x
- rwidth
) / 2;
327 else if (m_flag
& wxALIGN_RIGHT
)
328 pos
.x
+= (size
.x
- rwidth
);
333 // This is what GetPosition() returns. Since we calculate
334 // borders afterwards, GetPosition() will be the left/top
335 // corner of the surrounding border.
347 if (m_flag
& wxNORTH
)
352 if (m_flag
& wxSOUTH
)
362 m_rect
= wxRect(pos
, size
);
367 wxFAIL_MSG( _T("can't set size of uninitialized sizer item") );
371 m_window
->SetSize(pos
.x
, pos
.y
, size
.x
, size
.y
,
372 wxSIZE_ALLOW_MINUS_ONE
);
376 m_sizer
->SetDimension(pos
.x
, pos
.y
, size
.x
, size
.y
);
380 m_spacer
->SetSize(size
);
385 wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") );
389 void wxSizerItem::DeleteWindows()
398 //We are deleting the window from this sizer - normally
399 //the window destroys the sizer associated with it,
400 //which might destroy this, which we don't want
401 m_window
->SetContainingSizer(NULL
);
403 //Putting this after the switch will result in a spacer
404 //not being deleted properly on destruction
409 m_sizer
->DeleteWindows();
414 wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") );
419 void wxSizerItem::Show( bool show
)
424 wxFAIL_MSG( _T("can't show uninitialized sizer item") );
428 m_window
->Show(show
);
436 m_spacer
->Show(show
);
441 wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") );
445 bool wxSizerItem::IsShown() const
450 // we may be called from CalcMin(), just return false so that we're
455 return m_window
->IsShown();
458 // arbitrarily decide that if at least one of our elements is
459 // shown, so are we (this arbitrariness is the reason for
460 // deprecating this function)
462 for ( wxSizerItemList::compatibility_iterator
463 node
= m_sizer
->GetChildren().GetFirst();
465 node
= node
->GetNext() )
467 if ( node
->GetData()->IsShown() )
474 return m_spacer
->IsShown();
478 wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") );
484 #if WXWIN_COMPATIBILITY_2_6
485 void wxSizerItem::SetOption( int option
)
487 SetProportion( option
);
490 int wxSizerItem::GetOption() const
492 return GetProportion();
494 #endif // WXWIN_COMPATIBILITY_2_6
497 //---------------------------------------------------------------------------
499 //---------------------------------------------------------------------------
503 WX_CLEAR_LIST(wxSizerItemList
, m_children
);
506 wxSizerItem
* wxSizer::Insert( size_t index
, wxSizerItem
*item
)
508 m_children
.Insert( index
, item
);
510 if ( item
->GetWindow() )
511 item
->GetWindow()->SetContainingSizer( this );
516 void wxSizer::SetContainingWindow(wxWindow
*win
)
518 if ( win
== m_containingWindow
)
521 m_containingWindow
= win
;
523 // set the same window for all nested sizers as well, they also are in the
525 for ( wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
527 node
= node
->GetNext() )
529 wxSizerItem
*const item
= node
->GetData();
530 wxSizer
*const sizer
= item
->GetSizer();
534 sizer
->SetContainingWindow(win
);
539 #if WXWIN_COMPATIBILITY_2_6
540 bool wxSizer::Remove( wxWindow
*window
)
542 return Detach( window
);
544 #endif // WXWIN_COMPATIBILITY_2_6
546 bool wxSizer::Remove( wxSizer
*sizer
)
548 wxASSERT_MSG( sizer
, _T("Removing NULL sizer") );
550 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
553 wxSizerItem
*item
= node
->GetData();
555 if (item
->GetSizer() == sizer
)
558 m_children
.Erase( node
);
562 node
= node
->GetNext();
568 bool wxSizer::Remove( int index
)
570 wxCHECK_MSG( index
>= 0 && (size_t)index
< m_children
.GetCount(),
572 _T("Remove index is out of range") );
574 wxSizerItemList::compatibility_iterator node
= m_children
.Item( index
);
576 wxCHECK_MSG( node
, false, _T("Failed to find child node") );
578 wxSizerItem
*item
= node
->GetData();
580 if ( item
->IsWindow() )
581 item
->GetWindow()->SetContainingSizer( NULL
);
584 m_children
.Erase( node
);
588 bool wxSizer::Detach( wxSizer
*sizer
)
590 wxASSERT_MSG( sizer
, _T("Detaching NULL sizer") );
592 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
595 wxSizerItem
*item
= node
->GetData();
597 if (item
->GetSizer() == sizer
)
601 m_children
.Erase( node
);
604 node
= node
->GetNext();
610 bool wxSizer::Detach( wxWindow
*window
)
612 wxASSERT_MSG( window
, _T("Detaching NULL window") );
614 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
617 wxSizerItem
*item
= node
->GetData();
619 if (item
->GetWindow() == window
)
621 item
->GetWindow()->SetContainingSizer( NULL
);
623 m_children
.Erase( node
);
626 node
= node
->GetNext();
632 bool wxSizer::Detach( int index
)
634 wxCHECK_MSG( index
>= 0 && (size_t)index
< m_children
.GetCount(),
636 _T("Detach index is out of range") );
638 wxSizerItemList::compatibility_iterator node
= m_children
.Item( index
);
640 wxCHECK_MSG( node
, false, _T("Failed to find child node") );
642 wxSizerItem
*item
= node
->GetData();
644 if ( item
->IsSizer() )
646 else if ( item
->IsWindow() )
647 item
->GetWindow()->SetContainingSizer( NULL
);
650 m_children
.Erase( node
);
654 bool wxSizer::Replace( wxWindow
*oldwin
, wxWindow
*newwin
, bool recursive
)
656 wxASSERT_MSG( oldwin
, _T("Replacing NULL window") );
657 wxASSERT_MSG( newwin
, _T("Replacing with NULL window") );
659 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
662 wxSizerItem
*item
= node
->GetData();
664 if (item
->GetWindow() == oldwin
)
666 item
->GetWindow()->SetContainingSizer( NULL
);
667 item
->SetWindow(newwin
);
668 newwin
->SetContainingSizer( this );
671 else if (recursive
&& item
->IsSizer())
673 if (item
->GetSizer()->Replace( oldwin
, newwin
, true ))
677 node
= node
->GetNext();
683 bool wxSizer::Replace( wxSizer
*oldsz
, wxSizer
*newsz
, bool recursive
)
685 wxASSERT_MSG( oldsz
, _T("Replacing NULL sizer") );
686 wxASSERT_MSG( newsz
, _T("Replacing with NULL sizer") );
688 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
691 wxSizerItem
*item
= node
->GetData();
693 if (item
->GetSizer() == oldsz
)
695 wxSizer
*old
= item
->GetSizer();
696 item
->SetSizer(newsz
);
700 else if (recursive
&& item
->IsSizer())
702 if (item
->GetSizer()->Replace( oldsz
, newsz
, true ))
706 node
= node
->GetNext();
712 bool wxSizer::Replace( size_t old
, wxSizerItem
*newitem
)
714 wxCHECK_MSG( old
< m_children
.GetCount(), false, _T("Replace index is out of range") );
715 wxASSERT_MSG( newitem
, _T("Replacing with NULL item") );
717 wxSizerItemList::compatibility_iterator node
= m_children
.Item( old
);
719 wxCHECK_MSG( node
, false, _T("Failed to find child node") );
721 wxSizerItem
*item
= node
->GetData();
722 node
->SetData(newitem
);
728 void wxSizer::Clear( bool delete_windows
)
730 // First clear the ContainingSizer pointers
731 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
734 wxSizerItem
*item
= node
->GetData();
736 if (item
->IsWindow())
737 item
->GetWindow()->SetContainingSizer( NULL
);
738 node
= node
->GetNext();
741 // Destroy the windows if needed
745 // Now empty the list
746 WX_CLEAR_LIST(wxSizerItemList
, m_children
);
749 void wxSizer::DeleteWindows()
751 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
754 wxSizerItem
*item
= node
->GetData();
756 item
->DeleteWindows();
757 node
= node
->GetNext();
761 wxSize
wxSizer::Fit( wxWindow
*window
)
763 wxSize
size(window
->IsTopLevel() ? FitSize(window
)
764 : GetMinWindowSize(window
));
766 window
->SetSize( size
);
771 void wxSizer::FitInside( wxWindow
*window
)
774 if (window
->IsTopLevel())
775 size
= VirtualFitSize( window
);
777 size
= GetMinClientSize( window
);
779 window
->SetVirtualSize( size
);
782 void wxSizer::Layout()
784 // (re)calculates minimums needed for each item and other preparations
788 // Applies the layout and repositions/resizes the items
792 void wxSizer::SetSizeHints( wxWindow
*window
)
794 // Preserve the window's max size hints, but set the
795 // lower bound according to the sizer calculations.
797 wxSize size
= Fit( window
);
799 window
->SetSizeHints( size
.x
,
801 window
->GetMaxWidth(),
802 window
->GetMaxHeight() );
805 void wxSizer::SetVirtualSizeHints( wxWindow
*window
)
807 // Preserve the window's max size hints, but set the
808 // lower bound according to the sizer calculations.
811 wxSize
size( window
->GetVirtualSize() );
812 window
->SetVirtualSizeHints( size
.x
,
814 window
->GetMaxWidth(),
815 window
->GetMaxHeight() );
818 wxSize
wxSizer::GetMaxWindowSize( wxWindow
*window
) const
820 return window
->GetMaxSize();
823 wxSize
wxSizer::GetMinWindowSize( wxWindow
*window
)
825 wxSize
minSize( GetMinSize() );
826 wxSize
size( window
->GetSize() );
827 wxSize
client_size( window
->GetClientSize() );
829 return wxSize( minSize
.x
+size
.x
-client_size
.x
,
830 minSize
.y
+size
.y
-client_size
.y
);
833 // TODO on mac we need a function that determines how much free space this
834 // min size contains, in order to make sure that we have 20 pixels of free
835 // space around the controls
837 // Return a window size that will fit within the screens dimensions
838 wxSize
wxSizer::FitSize( wxWindow
*window
)
840 if ( window
->IsTopLevel() )
842 wxTopLevelWindow
*tlw
= wxDynamicCast(window
, wxTopLevelWindow
);
843 if ( tlw
&& tlw
->IsAlwaysMaximized() )
845 return tlw
->GetClientSize();
849 wxSize size
= GetMinWindowSize( window
);
850 wxSize sizeMax
= GetMaxWindowSize( window
);
852 // Limit the size if sizeMax != wxDefaultSize
854 if ( size
.x
> sizeMax
.x
&& sizeMax
.x
!= wxDefaultCoord
)
856 if ( size
.y
> sizeMax
.y
&& sizeMax
.y
!= wxDefaultCoord
)
862 wxSize
wxSizer::GetMaxClientSize( wxWindow
*window
) const
864 wxSize
maxSize( window
->GetMaxSize() );
866 if ( maxSize
!= wxDefaultSize
)
868 wxSize
size( window
->GetSize() );
869 wxSize
client_size( window
->GetClientSize() );
871 return wxSize( maxSize
.x
+ client_size
.x
- size
.x
,
872 maxSize
.y
+ client_size
.y
- size
.y
);
875 return wxDefaultSize
;
878 wxSize
wxSizer::GetMinClientSize( wxWindow
*WXUNUSED(window
) )
880 return GetMinSize(); // Already returns client size.
883 wxSize
wxSizer::VirtualFitSize( wxWindow
*window
)
885 wxSize size
= GetMinClientSize( window
);
886 wxSize sizeMax
= GetMaxClientSize( window
);
888 // Limit the size if sizeMax != wxDefaultSize
890 if ( size
.x
> sizeMax
.x
&& sizeMax
.x
!= wxDefaultCoord
)
892 if ( size
.y
> sizeMax
.y
&& sizeMax
.y
!= wxDefaultCoord
)
898 void wxSizer::SetDimension( int x
, int y
, int width
, int height
)
907 wxSize
wxSizer::GetMinSize()
909 wxSize
ret( CalcMin() );
910 if (ret
.x
< m_minSize
.x
) ret
.x
= m_minSize
.x
;
911 if (ret
.y
< m_minSize
.y
) ret
.y
= m_minSize
.y
;
915 void wxSizer::DoSetMinSize( int width
, int height
)
918 m_minSize
.y
= height
;
921 bool wxSizer::DoSetItemMinSize( wxWindow
*window
, int width
, int height
)
923 wxASSERT_MSG( window
, _T("SetMinSize for NULL window") );
925 // Is it our immediate child?
927 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
930 wxSizerItem
*item
= node
->GetData();
932 if (item
->GetWindow() == window
)
934 item
->SetMinSize( width
, height
);
937 node
= node
->GetNext();
940 // No? Search any subsizers we own then
942 node
= m_children
.GetFirst();
945 wxSizerItem
*item
= node
->GetData();
947 if ( item
->GetSizer() &&
948 item
->GetSizer()->DoSetItemMinSize( window
, width
, height
) )
950 // A child sizer found the requested windw, exit.
953 node
= node
->GetNext();
959 bool wxSizer::DoSetItemMinSize( wxSizer
*sizer
, int width
, int height
)
961 wxASSERT_MSG( sizer
, _T("SetMinSize for NULL sizer") );
963 // Is it our immediate child?
965 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
968 wxSizerItem
*item
= node
->GetData();
970 if (item
->GetSizer() == sizer
)
972 item
->GetSizer()->DoSetMinSize( width
, height
);
975 node
= node
->GetNext();
978 // No? Search any subsizers we own then
980 node
= m_children
.GetFirst();
983 wxSizerItem
*item
= node
->GetData();
985 if ( item
->GetSizer() &&
986 item
->GetSizer()->DoSetItemMinSize( sizer
, width
, height
) )
988 // A child found the requested sizer, exit.
991 node
= node
->GetNext();
997 bool wxSizer::DoSetItemMinSize( size_t index
, int width
, int height
)
999 wxSizerItemList::compatibility_iterator node
= m_children
.Item( index
);
1001 wxCHECK_MSG( node
, false, _T("Failed to find child node") );
1003 wxSizerItem
*item
= node
->GetData();
1005 if (item
->GetSizer())
1007 // Sizers contains the minimal size in them, if not calculated ...
1008 item
->GetSizer()->DoSetMinSize( width
, height
);
1012 // ... but the minimal size of spacers and windows is stored via the item
1013 item
->SetMinSize( width
, height
);
1019 wxSizerItem
* wxSizer::GetItem( wxWindow
*window
, bool recursive
)
1021 wxASSERT_MSG( window
, _T("GetItem for NULL window") );
1023 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
1026 wxSizerItem
*item
= node
->GetData();
1028 if (item
->GetWindow() == window
)
1032 else if (recursive
&& item
->IsSizer())
1034 wxSizerItem
*subitem
= item
->GetSizer()->GetItem( window
, true );
1039 node
= node
->GetNext();
1045 wxSizerItem
* wxSizer::GetItem( wxSizer
*sizer
, bool recursive
)
1047 wxASSERT_MSG( sizer
, _T("GetItem for NULL sizer") );
1049 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
1052 wxSizerItem
*item
= node
->GetData();
1054 if (item
->GetSizer() == sizer
)
1058 else if (recursive
&& item
->IsSizer())
1060 wxSizerItem
*subitem
= item
->GetSizer()->GetItem( sizer
, true );
1065 node
= node
->GetNext();
1071 wxSizerItem
* wxSizer::GetItem( size_t index
)
1073 wxCHECK_MSG( index
< m_children
.GetCount(),
1075 _T("GetItem index is out of range") );
1077 return m_children
.Item( index
)->GetData();
1080 bool wxSizer::Show( wxWindow
*window
, bool show
, bool recursive
)
1082 wxSizerItem
*item
= GetItem( window
, recursive
);
1093 bool wxSizer::Show( wxSizer
*sizer
, bool show
, bool recursive
)
1095 wxSizerItem
*item
= GetItem( sizer
, recursive
);
1106 bool wxSizer::Show( size_t index
, bool show
)
1108 wxSizerItem
*item
= GetItem( index
);
1119 void wxSizer::ShowItems( bool show
)
1121 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
1124 node
->GetData()->Show( show
);
1125 node
= node
->GetNext();
1129 bool wxSizer::IsShown( wxWindow
*window
) const
1131 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
1134 wxSizerItem
*item
= node
->GetData();
1136 if (item
->GetWindow() == window
)
1138 return item
->IsShown();
1140 node
= node
->GetNext();
1143 wxFAIL_MSG( _T("IsShown failed to find sizer item") );
1148 bool wxSizer::IsShown( wxSizer
*sizer
) const
1150 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
1153 wxSizerItem
*item
= node
->GetData();
1155 if (item
->GetSizer() == sizer
)
1157 return item
->IsShown();
1159 node
= node
->GetNext();
1162 wxFAIL_MSG( _T("IsShown failed to find sizer item") );
1167 bool wxSizer::IsShown( size_t index
) const
1169 wxCHECK_MSG( index
< m_children
.GetCount(),
1171 _T("IsShown index is out of range") );
1173 return m_children
.Item( index
)->GetData()->IsShown();
1177 //---------------------------------------------------------------------------
1179 //---------------------------------------------------------------------------
1181 wxGridSizer::wxGridSizer( int rows
, int cols
, int vgap
, int hgap
)
1182 : m_rows( ( cols
== 0 && rows
== 0 ) ? 1 : rows
)
1189 wxGridSizer::wxGridSizer( int cols
, int vgap
, int hgap
)
1190 : m_rows( cols
== 0 ? 1 : 0 )
1197 int wxGridSizer::CalcRowsCols(int& nrows
, int& ncols
) const
1199 int nitems
= m_children
.GetCount();
1205 nrows
= (nitems
+ m_cols
- 1) / m_cols
;
1209 ncols
= (nitems
+ m_rows
- 1) / m_rows
;
1212 else // 0 columns, 0 rows?
1214 wxFAIL_MSG( _T("grid sizer must have either rows or columns fixed") );
1223 void wxGridSizer::RecalcSizes()
1225 int nitems
, nrows
, ncols
;
1226 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
1229 wxSize
sz( GetSize() );
1230 wxPoint
pt( GetPosition() );
1232 int w
= (sz
.x
- (ncols
- 1) * m_hgap
) / ncols
;
1233 int h
= (sz
.y
- (nrows
- 1) * m_vgap
) / nrows
;
1236 for (int c
= 0; c
< ncols
; c
++)
1239 for (int r
= 0; r
< nrows
; r
++)
1241 int i
= r
* ncols
+ c
;
1244 wxSizerItemList::compatibility_iterator node
= m_children
.Item( i
);
1246 wxASSERT_MSG( node
, _T("Failed to find SizerItemList node") );
1248 SetItemBounds( node
->GetData(), x
, y
, w
, h
);
1256 wxSize
wxGridSizer::CalcMin()
1259 if ( CalcRowsCols(nrows
, ncols
) == 0 )
1262 // Find the max width and height for any component
1266 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
1269 wxSizerItem
*item
= node
->GetData();
1270 wxSize
sz( item
->CalcMin() );
1272 w
= wxMax( w
, sz
.x
);
1273 h
= wxMax( h
, sz
.y
);
1275 node
= node
->GetNext();
1278 return wxSize( ncols
* w
+ (ncols
-1) * m_hgap
,
1279 nrows
* h
+ (nrows
-1) * m_vgap
);
1282 void wxGridSizer::SetItemBounds( wxSizerItem
*item
, int x
, int y
, int w
, int h
)
1285 wxSize
sz( item
->GetMinSizeWithBorder() );
1286 int flag
= item
->GetFlag();
1288 if ((flag
& wxEXPAND
) || (flag
& wxSHAPED
))
1294 if (flag
& wxALIGN_CENTER_HORIZONTAL
)
1296 pt
.x
= x
+ (w
- sz
.x
) / 2;
1298 else if (flag
& wxALIGN_RIGHT
)
1300 pt
.x
= x
+ (w
- sz
.x
);
1303 if (flag
& wxALIGN_CENTER_VERTICAL
)
1305 pt
.y
= y
+ (h
- sz
.y
) / 2;
1307 else if (flag
& wxALIGN_BOTTOM
)
1309 pt
.y
= y
+ (h
- sz
.y
);
1313 item
->SetDimension(pt
, sz
);
1316 //---------------------------------------------------------------------------
1318 //---------------------------------------------------------------------------
1320 wxFlexGridSizer::wxFlexGridSizer( int rows
, int cols
, int vgap
, int hgap
)
1321 : wxGridSizer( rows
, cols
, vgap
, hgap
),
1322 m_flexDirection(wxBOTH
),
1323 m_growMode(wxFLEX_GROWMODE_SPECIFIED
)
1327 wxFlexGridSizer::wxFlexGridSizer( int cols
, int vgap
, int hgap
)
1328 : wxGridSizer( cols
, vgap
, hgap
),
1329 m_flexDirection(wxBOTH
),
1330 m_growMode(wxFLEX_GROWMODE_SPECIFIED
)
1334 wxFlexGridSizer::~wxFlexGridSizer()
1338 void wxFlexGridSizer::RecalcSizes()
1340 int nitems
, nrows
, ncols
;
1341 if ( (nitems
= CalcRowsCols(nrows
, ncols
)) == 0 )
1344 wxPoint
pt( GetPosition() );
1345 wxSize
sz( GetSize() );
1347 AdjustForGrowables(sz
, m_calculatedMinSize
, nrows
, ncols
);
1349 sz
= wxSize( pt
.x
+ sz
.x
, pt
.y
+ sz
.y
);
1352 for (int c
= 0; c
< ncols
; c
++)
1355 for (int r
= 0; r
< nrows
; r
++)
1357 int i
= r
* ncols
+ c
;
1360 wxSizerItemList::compatibility_iterator node
= m_children
.Item( i
);
1362 wxASSERT_MSG( node
, _T("Failed to find node") );
1364 int w
= wxMax( 0, wxMin( m_colWidths
[c
], sz
.x
- x
) );
1365 int h
= wxMax( 0, wxMin( m_rowHeights
[r
], sz
.y
- y
) );
1367 SetItemBounds( node
->GetData(), x
, y
, w
, h
);
1369 if (m_rowHeights
[r
] != -1)
1370 y
= y
+ m_rowHeights
[r
] + m_vgap
;
1372 if (m_colWidths
[c
] != -1)
1373 x
= x
+ m_colWidths
[c
] + m_hgap
;
1377 wxSize
wxFlexGridSizer::CalcMin()
1383 // Number of rows/columns can change as items are added or removed.
1384 if ( !CalcRowsCols(nrows
, ncols
) )
1387 m_rowHeights
.SetCount(nrows
);
1388 m_colWidths
.SetCount(ncols
);
1390 // We have to recalcuate the sizes in case the item minimum size has
1391 // changed since the previous layout, or the item has been hidden using
1392 // wxSizer::Show(). If all the items in a row/column are hidden, the final
1393 // dimension of the row/column will be -1, indicating that the column
1394 // itself is hidden.
1395 for( s
= m_rowHeights
.GetCount(), i
= 0; i
< s
; ++i
)
1396 m_rowHeights
[ i
] = -1;
1397 for( s
= m_colWidths
.GetCount(), i
= 0; i
< s
; ++i
)
1398 m_colWidths
[ i
] = -1;
1400 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
1405 wxSizerItem
*item
= node
->GetData();
1406 if ( item
->IsShown() )
1408 wxSize
sz( item
->CalcMin() );
1409 int row
= i
/ ncols
;
1410 int col
= i
% ncols
;
1412 m_rowHeights
[ row
] = wxMax( wxMax( 0, sz
.y
), m_rowHeights
[ row
] );
1413 m_colWidths
[ col
] = wxMax( wxMax( 0, sz
.x
), m_colWidths
[ col
] );
1416 node
= node
->GetNext();
1420 AdjustForFlexDirection();
1422 // Sum total minimum size, including gaps between rows/columns.
1423 // -1 is used as a magic number meaning empty column.
1425 for (int col
= 0; col
< ncols
; col
++)
1426 if ( m_colWidths
[ col
] != -1 )
1427 width
+= m_colWidths
[ col
] + m_hgap
;
1432 for (int row
= 0; row
< nrows
; row
++)
1433 if ( m_rowHeights
[ row
] != -1 )
1434 height
+= m_rowHeights
[ row
] + m_vgap
;
1438 m_calculatedMinSize
= wxSize( width
, height
);
1439 return m_calculatedMinSize
;
1442 void wxFlexGridSizer::AdjustForFlexDirection()
1444 // the logic in CalcMin works when we resize flexibly in both directions
1445 // but maybe this is not the case
1446 if ( m_flexDirection
!= wxBOTH
)
1448 // select the array corresponding to the direction in which we do *not*
1450 wxArrayInt
& array
= m_flexDirection
== wxVERTICAL
? m_colWidths
1453 const size_t count
= array
.GetCount();
1455 // find the largest value in this array
1459 for ( n
= 0; n
< count
; ++n
)
1461 if ( array
[n
] > largest
)
1465 // and now fill it with the largest value
1466 for ( n
= 0; n
< count
; ++n
)
1474 void wxFlexGridSizer::AdjustForGrowables(const wxSize
& sz
, const wxSize
& minsz
,
1475 int nrows
, int ncols
)
1477 // what to do with the rows? by default, resize them proportionally
1478 if ( sz
.y
> minsz
.y
&& ( (m_flexDirection
& wxVERTICAL
) || (m_growMode
== wxFLEX_GROWMODE_SPECIFIED
) ) )
1480 int sum_proportions
= 0;
1481 int growable_space
= 0;
1484 for (idx
= 0; idx
< m_growableRows
.GetCount(); idx
++)
1486 // Since the number of rows/columns can change as items are
1487 // inserted/deleted, we need to verify at runtime that the
1488 // requested growable rows/columns are still valid.
1489 if (m_growableRows
[idx
] >= nrows
)
1492 // If all items in a row/column are hidden, that row/column will
1493 // have a dimension of -1. This causes the row/column to be
1494 // hidden completely.
1495 if (m_rowHeights
[ m_growableRows
[idx
] ] == -1)
1497 sum_proportions
+= m_growableRowsProportions
[idx
];
1498 growable_space
+= m_rowHeights
[ m_growableRows
[idx
] ];
1504 for (idx
= 0; idx
< m_growableRows
.GetCount(); idx
++)
1506 if (m_growableRows
[idx
] >= nrows
)
1508 if (m_rowHeights
[ m_growableRows
[idx
] ] == -1)
1509 m_rowHeights
[ m_growableRows
[idx
] ] = 0;
1512 int delta
= (sz
.y
- minsz
.y
);
1513 if (sum_proportions
== 0)
1514 delta
= (delta
/num
) + m_rowHeights
[ m_growableRows
[idx
] ];
1516 delta
= ((delta
+growable_space
)*m_growableRowsProportions
[idx
]) / sum_proportions
;
1517 m_rowHeights
[ m_growableRows
[idx
] ] = delta
;
1522 else if ( (m_growMode
== wxFLEX_GROWMODE_ALL
) && (sz
.y
> minsz
.y
) )
1524 // rounding problem?
1525 for ( int row
= 0; row
< nrows
; ++row
)
1526 m_rowHeights
[ row
] = sz
.y
/ nrows
;
1529 // the same logic as above but for the columns
1530 if ( sz
.x
> minsz
.x
&& ( (m_flexDirection
& wxHORIZONTAL
) || (m_growMode
== wxFLEX_GROWMODE_SPECIFIED
) ) )
1532 int sum_proportions
= 0;
1533 int growable_space
= 0;
1536 for (idx
= 0; idx
< m_growableCols
.GetCount(); idx
++)
1538 // Since the number of rows/columns can change as items are
1539 // inserted/deleted, we need to verify at runtime that the
1540 // requested growable rows/columns are still valid.
1541 if (m_growableCols
[idx
] >= ncols
)
1544 // If all items in a row/column are hidden, that row/column will
1545 // have a dimension of -1. This causes the column to be hidden
1547 if (m_colWidths
[ m_growableCols
[idx
] ] == -1)
1549 sum_proportions
+= m_growableColsProportions
[idx
];
1550 growable_space
+= m_colWidths
[ m_growableCols
[idx
] ];
1556 for (idx
= 0; idx
< m_growableCols
.GetCount(); idx
++)
1558 if (m_growableCols
[idx
] >= ncols
)
1560 if (m_colWidths
[ m_growableCols
[idx
] ] == -1)
1561 m_colWidths
[ m_growableCols
[idx
] ] = 0;
1564 int delta
= (sz
.x
- minsz
.x
);
1565 if (sum_proportions
== 0)
1566 delta
= (delta
/num
) + m_colWidths
[ m_growableCols
[idx
] ];
1568 delta
= ((delta
+growable_space
)*m_growableColsProportions
[idx
])/sum_proportions
;
1569 m_colWidths
[ m_growableCols
[idx
] ] = delta
;
1574 else if ( (m_growMode
== wxFLEX_GROWMODE_ALL
) && (sz
.x
> minsz
.x
) )
1576 for ( int col
=0; col
< ncols
; ++col
)
1577 m_colWidths
[ col
] = sz
.x
/ ncols
;
1582 void wxFlexGridSizer::AddGrowableRow( size_t idx
, int proportion
)
1584 m_growableRows
.Add( idx
);
1585 m_growableRowsProportions
.Add( proportion
);
1588 void wxFlexGridSizer::AddGrowableCol( size_t idx
, int proportion
)
1590 m_growableCols
.Add( idx
);
1591 m_growableColsProportions
.Add( proportion
);
1594 // helper function for RemoveGrowableCol/Row()
1596 DoRemoveFromArrays(size_t idx
, wxArrayInt
& items
, wxArrayInt
& proportions
)
1598 const size_t count
= items
.size();
1599 for ( size_t n
= 0; n
< count
; n
++ )
1601 if ( (size_t)items
[n
] == idx
)
1604 proportions
.RemoveAt(n
);
1609 wxFAIL_MSG( _T("column/row is already not growable") );
1612 void wxFlexGridSizer::RemoveGrowableCol( size_t idx
)
1614 DoRemoveFromArrays(idx
, m_growableCols
, m_growableColsProportions
);
1617 void wxFlexGridSizer::RemoveGrowableRow( size_t idx
)
1619 DoRemoveFromArrays(idx
, m_growableRows
, m_growableRowsProportions
);
1622 //---------------------------------------------------------------------------
1624 //---------------------------------------------------------------------------
1626 wxBoxSizer::wxBoxSizer( int orient
)
1627 : m_orient( orient
)
1631 void wxBoxSizer::RecalcSizes()
1633 if (m_children
.GetCount() == 0)
1639 if (m_orient
== wxHORIZONTAL
)
1640 delta
= m_size
.x
- m_fixedWidth
;
1642 delta
= m_size
.y
- m_fixedHeight
;
1645 wxPoint
pt( m_position
);
1647 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
1650 wxSizerItem
*item
= node
->GetData();
1652 if (item
->IsShown())
1654 wxSize
size( item
->GetMinSizeWithBorder() );
1656 if (m_orient
== wxVERTICAL
)
1658 wxCoord height
= size
.y
;
1659 if (item
->GetProportion())
1661 // Because of at least one visible item has non-zero
1662 // proportion then m_stretchable is not zero
1663 height
= (delta
* item
->GetProportion()) / m_stretchable
;
1666 wxPoint
child_pos( pt
);
1667 wxSize
child_size( size
.x
, height
);
1669 if (item
->GetFlag() & (wxEXPAND
| wxSHAPED
))
1670 child_size
.x
= m_size
.x
;
1671 else if (item
->GetFlag() & wxALIGN_RIGHT
)
1672 child_pos
.x
+= m_size
.x
- size
.x
;
1673 else if (item
->GetFlag() & (wxCENTER
| wxALIGN_CENTER_HORIZONTAL
))
1674 // XXX wxCENTER is added for backward compatibility;
1675 // wxALIGN_CENTER should be used in new code
1676 child_pos
.x
+= (m_size
.x
- size
.x
) / 2;
1678 item
->SetDimension( child_pos
, child_size
);
1684 wxCoord width
= size
.x
;
1685 if (item
->GetProportion())
1687 // Because of at least one visible item has non-zero
1688 // proportion then m_stretchable is not zero
1689 width
= (delta
* item
->GetProportion()) / m_stretchable
;
1692 wxPoint
child_pos( pt
);
1693 wxSize
child_size( width
, size
.y
);
1695 if (item
->GetFlag() & (wxEXPAND
| wxSHAPED
))
1696 child_size
.y
= m_size
.y
;
1697 else if (item
->GetFlag() & wxALIGN_BOTTOM
)
1698 child_pos
.y
+= m_size
.y
- size
.y
;
1699 else if (item
->GetFlag() & (wxCENTER
| wxALIGN_CENTER_VERTICAL
))
1700 // XXX wxCENTER is added for backward compatibility;
1701 // wxALIGN_CENTER should be used in new code
1702 child_pos
.y
+= (m_size
.y
- size
.y
) / 2;
1704 if ( m_containingWindow
)
1706 child_pos
.x
= m_containingWindow
->AdjustForLayoutDirection
1714 item
->SetDimension( child_pos
, child_size
);
1720 node
= node
->GetNext();
1724 wxSize
wxBoxSizer::CalcMin()
1726 if (m_children
.GetCount() == 0)
1735 // precalc item minsizes and count proportions
1736 wxSizerItemList::compatibility_iterator node
= m_children
.GetFirst();
1739 wxSizerItem
*item
= node
->GetData();
1741 if ( item
->IsShown() )
1743 item
->CalcMin(); // result is stored in the item
1745 m_stretchable
+= item
->GetProportion();
1748 node
= node
->GetNext();
1751 // Total minimum size (width or height) of sizer
1754 node
= m_children
.GetFirst();
1757 wxSizerItem
*item
= node
->GetData();
1759 if (item
->IsShown() && item
->GetProportion() != 0)
1761 int stretch
= item
->GetProportion();
1762 wxSize
size( item
->GetMinSizeWithBorder() );
1765 // Integer division rounded up is (a + b - 1) / b
1766 // Round up needed in order to guarantee that all
1767 // all items will have size not less then their min size
1768 if (m_orient
== wxHORIZONTAL
)
1769 minSize
= ( size
.x
*m_stretchable
+ stretch
- 1)/stretch
;
1771 minSize
= ( size
.y
*m_stretchable
+ stretch
- 1)/stretch
;
1773 if (minSize
> maxMinSize
)
1774 maxMinSize
= minSize
;
1776 node
= node
->GetNext();
1779 // Calculate overall minimum size
1780 node
= m_children
.GetFirst();
1783 wxSizerItem
*item
= node
->GetData();
1785 if (item
->IsShown())
1787 wxSize
size( item
->GetMinSizeWithBorder() );
1788 if (item
->GetProportion() != 0)
1790 if (m_orient
== wxHORIZONTAL
)
1791 size
.x
= (maxMinSize
*item
->GetProportion())/m_stretchable
;
1793 size
.y
= (maxMinSize
*item
->GetProportion())/m_stretchable
;
1797 if (m_orient
== wxVERTICAL
)
1799 m_fixedHeight
+= size
.y
;
1800 m_fixedWidth
= wxMax( m_fixedWidth
, size
.x
);
1804 m_fixedWidth
+= size
.x
;
1805 m_fixedHeight
= wxMax( m_fixedHeight
, size
.y
);
1809 if (m_orient
== wxHORIZONTAL
)
1811 m_minWidth
+= size
.x
;
1812 m_minHeight
= wxMax( m_minHeight
, size
.y
);
1816 m_minHeight
+= size
.y
;
1817 m_minWidth
= wxMax( m_minWidth
, size
.x
);
1820 node
= node
->GetNext();
1823 return wxSize( m_minWidth
, m_minHeight
);
1826 //---------------------------------------------------------------------------
1828 //---------------------------------------------------------------------------
1832 wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox
*box
, int orient
)
1833 : wxBoxSizer( orient
),
1836 wxASSERT_MSG( box
, wxT("wxStaticBoxSizer needs a static box") );
1838 // do this so that our Detach() is called if the static box is destroyed
1840 m_staticBox
->SetContainingSizer(this);
1843 wxStaticBoxSizer::wxStaticBoxSizer(int orient
, wxWindow
*win
, const wxString
& s
)
1844 : wxBoxSizer(orient
),
1845 m_staticBox(new wxStaticBox(win
, wxID_ANY
, s
))
1848 m_staticBox
->SetContainingSizer(this);
1851 wxStaticBoxSizer::~wxStaticBoxSizer()
1856 static void GetStaticBoxBorders( wxStaticBox
*box
,
1860 // this has to be done platform by platform as there is no way to
1861 // guess the thickness of a wxStaticBox border
1862 box
->GetBordersForSizer(borderTop
, borderOther
);
1865 void wxStaticBoxSizer::RecalcSizes()
1867 int top_border
, other_border
;
1868 GetStaticBoxBorders(m_staticBox
, &top_border
, &other_border
);
1870 m_staticBox
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y
);
1872 wxPoint
old_pos( m_position
);
1873 m_position
.x
+= other_border
;
1874 m_position
.y
+= top_border
;
1875 wxSize
old_size( m_size
);
1876 m_size
.x
-= 2*other_border
;
1877 m_size
.y
-= top_border
+ other_border
;
1879 wxBoxSizer::RecalcSizes();
1881 m_position
= old_pos
;
1885 wxSize
wxStaticBoxSizer::CalcMin()
1887 int top_border
, other_border
;
1888 GetStaticBoxBorders(m_staticBox
, &top_border
, &other_border
);
1890 wxSize
ret( wxBoxSizer::CalcMin() );
1891 ret
.x
+= 2*other_border
;
1892 ret
.y
+= other_border
+ top_border
;
1897 void wxStaticBoxSizer::ShowItems( bool show
)
1899 m_staticBox
->Show( show
);
1900 wxBoxSizer::ShowItems( show
);
1903 bool wxStaticBoxSizer::Detach( wxWindow
*window
)
1905 // avoid deleting m_staticBox in our dtor if it's being detached from the
1906 // sizer (which can happen because it's being already destroyed for
1908 if ( window
== m_staticBox
)
1914 return wxSizer::Detach( window
);
1917 #endif // wxUSE_STATBOX
1921 wxStdDialogButtonSizer::wxStdDialogButtonSizer()
1922 : wxBoxSizer(wxHORIZONTAL
)
1924 // Vertical buttons with lots of space on either side
1925 // looks rubbish on WinCE, so let's not do this for now.
1926 // If we are going to use vertical buttons, we should
1927 // put the sizer to the right of other controls in the dialog,
1928 // and that's beyond the scope of this sizer.
1930 bool is_pda
= (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
);
1931 // If we have a PDA screen, put yes/no button over
1932 // all other buttons, otherwise on the left side.
1934 m_orient
= wxVERTICAL
;
1937 m_buttonAffirmative
= NULL
;
1938 m_buttonApply
= NULL
;
1939 m_buttonNegative
= NULL
;
1940 m_buttonCancel
= NULL
;
1941 m_buttonHelp
= NULL
;
1944 void wxStdDialogButtonSizer::AddButton(wxButton
*mybutton
)
1946 switch (mybutton
->GetId())
1951 m_buttonAffirmative
= mybutton
;
1954 m_buttonApply
= mybutton
;
1957 m_buttonNegative
= mybutton
;
1960 m_buttonCancel
= mybutton
;
1963 case wxID_CONTEXT_HELP
:
1964 m_buttonHelp
= mybutton
;
1971 void wxStdDialogButtonSizer::SetAffirmativeButton( wxButton
*button
)
1973 m_buttonAffirmative
= button
;
1976 void wxStdDialogButtonSizer::SetNegativeButton( wxButton
*button
)
1978 m_buttonNegative
= button
;
1981 void wxStdDialogButtonSizer::SetCancelButton( wxButton
*button
)
1983 m_buttonCancel
= button
;
1986 void wxStdDialogButtonSizer::Realize()
1989 Add(0, 0, 0, wxLEFT
, 6);
1991 Add((wxWindow
*)m_buttonHelp
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, 6);
1993 if (m_buttonNegative
){
1994 // HIG POLICE BULLETIN - destructive buttons need extra padding
1995 // 24 pixels on either side
1996 Add((wxWindow
*)m_buttonNegative
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, 12);
1999 // extra whitespace between help/negative and cancel/ok buttons
2000 Add(0, 0, 1, wxEXPAND
, 0);
2002 if (m_buttonCancel
){
2003 Add((wxWindow
*)m_buttonCancel
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, 6);
2004 // Cancel or help should be default
2005 // m_buttonCancel->SetDefaultButton();
2008 // Ugh, Mac doesn't really have apply dialogs, so I'll just
2009 // figure the best place is between Cancel and OK
2011 Add((wxWindow
*)m_buttonApply
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, 6);
2013 if (m_buttonAffirmative
){
2014 Add((wxWindow
*)m_buttonAffirmative
, 0, wxALIGN_CENTRE
| wxLEFT
, 6);
2016 if (m_buttonAffirmative
->GetId() == wxID_SAVE
){
2017 // these buttons have set labels under Mac so we should use them
2018 m_buttonAffirmative
->SetLabel(_("Save"));
2019 m_buttonNegative
->SetLabel(_("Don't Save"));
2023 // Extra space around and at the right
2025 #elif defined(__WXGTK20__)
2026 Add(0, 0, 0, wxLEFT
, 9);
2028 Add((wxWindow
*)m_buttonHelp
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, 3);
2030 // extra whitespace between help and cancel/ok buttons
2031 Add(0, 0, 1, wxEXPAND
, 0);
2033 if (m_buttonNegative
){
2034 Add((wxWindow
*)m_buttonNegative
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, 3);
2037 if (m_buttonCancel
){
2038 Add((wxWindow
*)m_buttonCancel
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, 3);
2039 // Cancel or help should be default
2040 // m_buttonCancel->SetDefaultButton();
2044 Add((wxWindow
*)m_buttonApply
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, 3);
2046 if (m_buttonAffirmative
)
2047 Add((wxWindow
*)m_buttonAffirmative
, 0, wxALIGN_CENTRE
| wxLEFT
, 6);
2048 #elif defined(__WXMSW__)
2051 // right-justify buttons
2052 Add(0, 0, 1, wxEXPAND
, 0);
2054 if (m_buttonAffirmative
){
2055 Add((wxWindow
*)m_buttonAffirmative
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, m_buttonAffirmative
->ConvertDialogToPixels(wxSize(2, 0)).x
);
2058 if (m_buttonNegative
){
2059 Add((wxWindow
*)m_buttonNegative
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, m_buttonNegative
->ConvertDialogToPixels(wxSize(2, 0)).x
);
2062 if (m_buttonCancel
){
2063 Add((wxWindow
*)m_buttonCancel
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, m_buttonCancel
->ConvertDialogToPixels(wxSize(2, 0)).x
);
2066 Add((wxWindow
*)m_buttonApply
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, m_buttonApply
->ConvertDialogToPixels(wxSize(2, 0)).x
);
2069 Add((wxWindow
*)m_buttonHelp
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, m_buttonHelp
->ConvertDialogToPixels(wxSize(2, 0)).x
);
2071 // GTK+1 and any other platform
2073 // Add(0, 0, 0, wxLEFT, 5); // Not sure what this was for but it unbalances the dialog
2075 Add((wxWindow
*)m_buttonHelp
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, m_buttonHelp
->ConvertDialogToPixels(wxSize(4, 0)).x
);
2077 // extra whitespace between help and cancel/ok buttons
2078 Add(0, 0, 1, wxEXPAND
, 0);
2081 Add((wxWindow
*)m_buttonApply
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, m_buttonApply
->ConvertDialogToPixels(wxSize(4, 0)).x
);
2083 if (m_buttonAffirmative
){
2084 Add((wxWindow
*)m_buttonAffirmative
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, m_buttonAffirmative
->ConvertDialogToPixels(wxSize(4, 0)).x
);
2087 if (m_buttonNegative
){
2088 Add((wxWindow
*)m_buttonNegative
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, m_buttonNegative
->ConvertDialogToPixels(wxSize(4, 0)).x
);
2091 if (m_buttonCancel
){
2092 Add((wxWindow
*)m_buttonCancel
, 0, wxALIGN_CENTRE
| wxLEFT
| wxRIGHT
, m_buttonCancel
->ConvertDialogToPixels(wxSize(4, 0)).x
);
2093 // Cancel or help should be default
2094 // m_buttonCancel->SetDefaultButton();
2100 #endif // wxUSE_BUTTON
2102 #if WXWIN_COMPATIBILITY_2_4
2104 // ----------------------------------------------------------------------------
2106 // ----------------------------------------------------------------------------
2109 IMPLEMENT_CLASS(wxBookCtrlSizer
, wxSizer
)
2111 IMPLEMENT_CLASS(wxNotebookSizer
, wxBookCtrlSizer
)
2112 #endif // wxUSE_NOTEBOOK
2113 #endif // wxUSE_BOOKCTRL
2117 #if WXWIN_COMPATIBILITY_2_6
2119 wxBookCtrlSizer::wxBookCtrlSizer(wxBookCtrlBase
*bookctrl
)
2120 : m_bookctrl(bookctrl
)
2122 wxASSERT_MSG( bookctrl
, wxT("wxBookCtrlSizer needs a control") );
2125 #endif // WXWIN_COMPATIBILITY_2_6
2127 void wxBookCtrlSizer::RecalcSizes()
2129 m_bookctrl
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y
);
2132 wxSize
wxBookCtrlSizer::CalcMin()
2134 wxSize sizeBorder
= m_bookctrl
->CalcSizeFromPage(wxSize(0,0));
2139 if ( m_bookctrl
->GetPageCount() == 0 )
2141 return wxSize(sizeBorder
.x
+ 10, sizeBorder
.y
+ 10);
2147 wxWindowList::compatibility_iterator
2148 node
= m_bookctrl
->GetChildren().GetFirst();
2151 wxWindow
*item
= node
->GetData();
2152 wxSizer
*itemsizer
= item
->GetSizer();
2156 wxSize
subsize( itemsizer
->CalcMin() );
2158 if (subsize
.x
> maxX
)
2160 if (subsize
.y
> maxY
)
2164 node
= node
->GetNext();
2167 return wxSize( maxX
, maxY
) + sizeBorder
;
2172 #if WXWIN_COMPATIBILITY_2_6
2174 wxNotebookSizer::wxNotebookSizer(wxNotebook
*nb
)
2176 wxASSERT_MSG( nb
, wxT("wxNotebookSizer needs a control") );
2180 #endif // WXWIN_COMPATIBILITY_2_6
2182 #endif // wxUSE_NOTEBOOOK
2183 #endif // wxUSE_BOOKCTRL
2185 #endif // WXWIN_COMPATIBILITY_2_4