]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/sizer.cpp
macro naming changes, delegate api calls getting property info, object info exposed...
[wxWidgets.git] / src / common / sizer.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: 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
7// Created:
8// RCS-ID: $Id$
9// Copyright: (c) Robin Dunn, Robert Roebling
10// Licence: wxWindows licence
11/////////////////////////////////////////////////////////////////////////////
12
13#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
14#pragma implementation "sizer.h"
15#endif
16
17// For compilers that support precompilation, includes "wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
21 #pragma hdrstop
22#endif
23
24#include "wx/sizer.h"
25#include "wx/utils.h"
26#include "wx/statbox.h"
27#include "wx/notebook.h"
28#include <wx/listimpl.cpp>
29
30//---------------------------------------------------------------------------
31
32IMPLEMENT_CLASS(wxSizerItem, wxObject)
33IMPLEMENT_CLASS(wxSizer, wxObject)
34IMPLEMENT_CLASS(wxGridSizer, wxSizer)
35IMPLEMENT_CLASS(wxFlexGridSizer, wxGridSizer)
36IMPLEMENT_CLASS(wxBoxSizer, wxSizer)
37#if wxUSE_STATBOX
38IMPLEMENT_CLASS(wxStaticBoxSizer, wxBoxSizer)
39#endif
40#if wxUSE_BOOKCTRL
41IMPLEMENT_CLASS(wxBookCtrlSizer, wxSizer)
42#if wxUSE_NOTEBOOK
43IMPLEMENT_CLASS(wxNotebookSizer, wxBookCtrlSizer)
44#endif // wxUSE_NOTEBOOK
45#endif // wxUSE_BOOKCTRL
46
47WX_DEFINE_EXPORTED_LIST( wxSizerItemList );
48
49/*
50 TODO PROPERTIES
51 sizeritem
52 object
53 object_ref
54 minsize
55 option
56 flag
57 border
58 spacer
59 option
60 flag
61 borfder
62 boxsizer
63 orient
64 staticboxsizer
65 orient
66 label
67 gridsizer
68 rows
69 cols
70 vgap
71 hgap
72 flexgridsizer
73 rows
74 cols
75 vgap
76 hgap
77 growablerows
78 growablecols
79 minsize
80*/
81//---------------------------------------------------------------------------
82// wxSizerItem
83//---------------------------------------------------------------------------
84
85wxSizerItem::wxSizerItem( int width, int height, int proportion, int flag, int border, wxObject* userData )
86 : m_window( NULL )
87 , m_sizer( NULL )
88 , m_size( wxSize( width, height ) ) // size is set directly
89 , m_minSize( m_size ) // minimal size is the initial size
90 , m_proportion( proportion )
91 , m_border( border )
92 , m_flag( flag )
93 , m_show( true )
94 , m_userData( userData )
95{
96 SetRatio( m_size );
97}
98
99wxSizerItem::wxSizerItem( wxWindow *window, int proportion, int flag, int border, wxObject* userData )
100 : m_window( window )
101 , m_sizer( NULL )
102 , m_minSize( window->GetSize() ) // minimal size is the initial size
103 , m_proportion( proportion )
104 , m_border( border )
105 , m_flag( flag )
106 , m_show( true )
107 , m_userData( userData )
108{
109 // aspect ratio calculated from initial size
110 SetRatio( m_minSize );
111
112 // m_size is calculated later
113}
114
115wxSizerItem::wxSizerItem( wxSizer *sizer, int proportion, int flag, int border, wxObject* userData )
116 : m_window( NULL )
117 , m_sizer( sizer )
118 , m_proportion( proportion )
119 , m_border( border )
120 , m_flag( flag )
121 , m_show( true )
122 , m_ratio( 0.0 )
123 , m_userData( userData )
124{
125 // m_minSize is calculated later
126 // m_size is calculated later
127}
128
129wxSizerItem::~wxSizerItem()
130{
131 delete m_userData;
132
133 if ( m_window )
134 {
135 m_window->SetContainingSizer(NULL);
136 }
137 else // we must be a sizer
138 {
139 delete m_sizer;
140 }
141}
142
143
144wxSize wxSizerItem::GetSize() const
145{
146 wxSize ret;
147 if (IsSizer())
148 ret = m_sizer->GetSize();
149 else
150 if (IsWindow())
151 ret = m_window->GetSize();
152 else ret = m_size;
153
154 if (m_flag & wxWEST)
155 ret.x += m_border;
156 if (m_flag & wxEAST)
157 ret.x += m_border;
158 if (m_flag & wxNORTH)
159 ret.y += m_border;
160 if (m_flag & wxSOUTH)
161 ret.y += m_border;
162
163 return ret;
164}
165
166wxSize wxSizerItem::CalcMin()
167{
168 wxSize ret;
169 if (IsSizer())
170 {
171 ret = m_sizer->GetMinSize();
172
173 // if we have to preserve aspect ratio _AND_ this is
174 // the first-time calculation, consider ret to be initial size
175 if ((m_flag & wxSHAPED) && !m_ratio)
176 SetRatio(ret);
177 }
178 else
179 {
180 if ( IsWindow() && (m_flag & wxADJUST_MINSIZE) )
181 {
182 // By user request, keep the minimal size for this item
183 // in sync with the largest of BestSize and any user supplied
184 // minimum size hint. Useful in cases where the item is
185 // changeable -- static text labels, etc.
186 m_minSize = m_window->GetAdjustedBestSize();
187 }
188
189 ret = m_minSize;
190 }
191
192 if (m_flag & wxWEST)
193 ret.x += m_border;
194 if (m_flag & wxEAST)
195 ret.x += m_border;
196 if (m_flag & wxNORTH)
197 ret.y += m_border;
198 if (m_flag & wxSOUTH)
199 ret.y += m_border;
200
201 return ret;
202}
203
204void wxSizerItem::SetDimension( wxPoint pos, wxSize size )
205{
206 if (m_flag & wxSHAPED)
207 {
208 // adjust aspect ratio
209 int rwidth = (int) (size.y * m_ratio);
210 if (rwidth > size.x)
211 {
212 // fit horizontally
213 int rheight = (int) (size.x / m_ratio);
214 // add vertical space
215 if (m_flag & wxALIGN_CENTER_VERTICAL)
216 pos.y += (size.y - rheight) / 2;
217 else if (m_flag & wxALIGN_BOTTOM)
218 pos.y += (size.y - rheight);
219 // use reduced dimensions
220 size.y =rheight;
221 }
222 else if (rwidth < size.x)
223 {
224 // add horizontal space
225 if (m_flag & wxALIGN_CENTER_HORIZONTAL)
226 pos.x += (size.x - rwidth) / 2;
227 else if (m_flag & wxALIGN_RIGHT)
228 pos.x += (size.x - rwidth);
229 size.x = rwidth;
230 }
231 }
232
233 // This is what GetPosition() returns. Since we calculate
234 // borders afterwards, GetPosition() will be the left/top
235 // corner of the surrounding border.
236 m_pos = pos;
237
238 if (m_flag & wxWEST)
239 {
240 pos.x += m_border;
241 size.x -= m_border;
242 }
243 if (m_flag & wxEAST)
244 {
245 size.x -= m_border;
246 }
247 if (m_flag & wxNORTH)
248 {
249 pos.y += m_border;
250 size.y -= m_border;
251 }
252 if (m_flag & wxSOUTH)
253 {
254 size.y -= m_border;
255 }
256
257 if (IsSizer())
258 m_sizer->SetDimension( pos.x, pos.y, size.x, size.y );
259
260 if (IsWindow())
261 m_window->SetSize( pos.x, pos.y, size.x, size.y, wxSIZE_ALLOW_MINUS_ONE );
262
263 m_size = size;
264}
265
266void wxSizerItem::DeleteWindows()
267{
268 if (m_window)
269 m_window->Destroy();
270
271 if (m_sizer)
272 m_sizer->DeleteWindows();
273}
274
275bool wxSizerItem::IsWindow() const
276{
277 return (m_window != NULL);
278}
279
280bool wxSizerItem::IsSizer() const
281{
282 return (m_sizer != NULL);
283}
284
285bool wxSizerItem::IsSpacer() const
286{
287 return (m_window == NULL) && (m_sizer == NULL);
288}
289
290void wxSizerItem::Show( bool show )
291{
292 m_show = show;
293
294 if( IsWindow() )
295 m_window->Show( show );
296 else if( IsSizer() )
297 m_sizer->ShowItems( show );
298
299 // ... nothing else to do to hide/show spacers
300}
301
302void wxSizerItem::SetOption( int option )
303{
304 SetProportion( option );
305}
306
307int wxSizerItem::GetOption() const
308{
309 return GetProportion();
310}
311
312
313//---------------------------------------------------------------------------
314// wxSizer
315//---------------------------------------------------------------------------
316
317wxSizer::wxSizer()
318 : m_minSize( wxSize( 0, 0 ) )
319{
320}
321
322wxSizer::~wxSizer()
323{
324 WX_CLEAR_LIST(wxSizerItemList, m_children);
325}
326
327void wxSizer::Add( wxWindow *window, int proportion, int flag, int border, wxObject* userData )
328{
329 m_children.Append( new wxSizerItem( window, proportion, flag, border, userData ) );
330 window->SetContainingSizer( this );
331}
332
333void wxSizer::Add( wxSizer *sizer, int proportion, int flag, int border, wxObject* userData )
334{
335 m_children.Append( new wxSizerItem( sizer, proportion, flag, border, userData ) );
336}
337
338void wxSizer::Add( int width, int height, int proportion, int flag, int border, wxObject* userData )
339{
340 m_children.Append( new wxSizerItem( width, height, proportion, flag, border, userData ) );
341}
342
343void wxSizer::Add( wxSizerItem *item )
344{
345 m_children.Append( item );
346
347 if( item->GetWindow() )
348 item->GetWindow()->SetContainingSizer( this );
349}
350
351void wxSizer::Prepend( wxWindow *window, int proportion, int flag, int border, wxObject* userData )
352{
353 m_children.Insert( new wxSizerItem( window, proportion, flag, border, userData ) );
354 window->SetContainingSizer( this );
355}
356
357void wxSizer::Prepend( wxSizer *sizer, int proportion, int flag, int border, wxObject* userData )
358{
359 m_children.Insert( new wxSizerItem( sizer, proportion, flag, border, userData ) );
360}
361
362void wxSizer::Prepend( int width, int height, int proportion, int flag, int border, wxObject* userData )
363{
364 m_children.Insert( new wxSizerItem( width, height, proportion, flag, border, userData ) );
365}
366
367void wxSizer::Prepend( wxSizerItem *item )
368{
369 m_children.Insert( item );
370
371 if( item->GetWindow() )
372 item->GetWindow()->SetContainingSizer( this );
373}
374
375void wxSizer::Insert( size_t index,
376 wxWindow *window,
377 int proportion,
378 int flag,
379 int border,
380 wxObject* userData )
381{
382 m_children.Insert( index,
383 new wxSizerItem( window, proportion, flag, border, userData ) );
384 window->SetContainingSizer( this );
385}
386
387void wxSizer::Insert( size_t index,
388 wxSizer *sizer,
389 int proportion,
390 int flag,
391 int border,
392 wxObject* userData )
393{
394 m_children.Insert( index,
395 new wxSizerItem( sizer, proportion, flag, border, userData ) );
396}
397
398void wxSizer::Insert( size_t index,
399 int width,
400 int height,
401 int proportion,
402 int flag,
403 int border,
404 wxObject* userData )
405{
406 m_children.Insert( index,
407 new wxSizerItem( width, height, proportion, flag, border, userData ) );
408}
409
410void wxSizer::Insert( size_t index, wxSizerItem *item )
411{
412 m_children.Insert( index, item );
413
414 if( item->GetWindow() )
415 item->GetWindow()->SetContainingSizer( this );
416}
417
418bool wxSizer::Remove( wxWindow *window )
419{
420 return Detach( window );
421}
422
423bool wxSizer::Remove( wxSizer *sizer )
424{
425 wxASSERT_MSG( sizer, _T("Removing NULL sizer") );
426
427 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
428 while (node)
429 {
430 wxSizerItem *item = node->GetData();
431
432 if (item->GetSizer() == sizer)
433 {
434 delete item;
435 m_children.Erase( node );
436 return true;
437 }
438
439 node = node->GetNext();
440 }
441
442 return false;
443}
444
445bool wxSizer::Remove( int index )
446{
447 wxCHECK_MSG( index >= 0 && (size_t)index < m_children.GetCount(),
448 false,
449 _T("Remove index is out of range") );
450
451 wxSizerItemList::compatibility_iterator node = m_children.Item( index );
452
453 wxCHECK_MSG( node, false, _T("Failed to find child node") );
454
455 wxSizerItem *item = node->GetData();
456
457 if( item->IsWindow() )
458 item->GetWindow()->SetContainingSizer( NULL );
459
460 delete item;
461 m_children.Erase( node );
462 return true;
463}
464
465bool wxSizer::Detach( wxSizer *sizer )
466{
467 wxASSERT_MSG( sizer, _T("Detaching NULL sizer") );
468
469 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
470 while (node)
471 {
472 wxSizerItem *item = node->GetData();
473
474 if (item->GetSizer() == sizer)
475 {
476 item->DetachSizer();
477 delete item;
478 m_children.Erase( node );
479 return true;
480 }
481 node = node->GetNext();
482 }
483
484 return false;
485}
486
487bool wxSizer::Detach( wxWindow *window )
488{
489 wxASSERT_MSG( window, _T("Detaching NULL window") );
490
491 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
492 while (node)
493 {
494 wxSizerItem *item = node->GetData();
495
496 if (item->GetWindow() == window)
497 {
498 item->GetWindow()->SetContainingSizer( NULL );
499 delete item;
500 m_children.Erase( node );
501 return true;
502 }
503 node = node->GetNext();
504 }
505
506 return false;
507}
508
509bool wxSizer::Detach( int index )
510{
511 wxCHECK_MSG( index >= 0 && (size_t)index < m_children.GetCount(),
512 false,
513 _T("Detach index is out of range") );
514
515 wxSizerItemList::compatibility_iterator node = m_children.Item( index );
516
517 wxCHECK_MSG( node, false, _T("Failed to find child node") );
518
519 wxSizerItem *item = node->GetData();
520
521 if( item->IsSizer() )
522 item->DetachSizer();
523 else if( item->IsWindow() )
524 item->GetWindow()->SetContainingSizer( NULL );
525
526 delete item;
527 m_children.Erase( node );
528 return true;
529}
530
531void wxSizer::Clear( bool delete_windows )
532{
533 // First clear the ContainingSizer pointers
534 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
535 while (node)
536 {
537 wxSizerItem *item = node->GetData();
538
539 if (item->IsWindow())
540 item->GetWindow()->SetContainingSizer( NULL );
541 node = node->GetNext();
542 }
543
544 // Destroy the windows if needed
545 if (delete_windows)
546 DeleteWindows();
547
548 // Now empty the list
549 WX_CLEAR_LIST(wxSizerItemList, m_children);
550}
551
552void wxSizer::DeleteWindows()
553{
554 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
555 while (node)
556 {
557 wxSizerItem *item = node->GetData();
558
559 item->DeleteWindows();
560 node = node->GetNext();
561 }
562}
563
564wxSize wxSizer::Fit( wxWindow *window )
565{
566 wxSize size(window->IsTopLevel() ? FitSize(window)
567 : GetMinWindowSize(window));
568
569 window->SetSize( size );
570
571 return size;
572}
573
574void wxSizer::FitInside( wxWindow *window )
575{
576 wxSize size;
577 if (window->IsTopLevel())
578 size = VirtualFitSize( window );
579 else
580 size = GetMinClientSize( window );
581
582 window->SetVirtualSize( size );
583}
584
585void wxSizer::Layout()
586{
587 CalcMin();
588 RecalcSizes();
589}
590
591void wxSizer::SetSizeHints( wxWindow *window )
592{
593 // Preserve the window's max size hints, but set the
594 // lower bound according to the sizer calculations.
595
596 wxSize size = Fit( window );
597
598 window->SetSizeHints( size.x,
599 size.y,
600 window->GetMaxWidth(),
601 window->GetMaxHeight() );
602}
603
604void wxSizer::SetVirtualSizeHints( wxWindow *window )
605{
606 // Preserve the window's max size hints, but set the
607 // lower bound according to the sizer calculations.
608
609 FitInside( window );
610 wxSize size( window->GetVirtualSize() );
611 window->SetVirtualSizeHints( size.x,
612 size.y,
613 window->GetMaxWidth(),
614 window->GetMaxHeight() );
615}
616
617wxSize wxSizer::GetMaxWindowSize( wxWindow *window ) const
618{
619 return window->GetMaxSize();
620}
621
622wxSize wxSizer::GetMinWindowSize( wxWindow *window )
623{
624 wxSize minSize( GetMinSize() );
625 wxSize size( window->GetSize() );
626 wxSize client_size( window->GetClientSize() );
627
628 return wxSize( minSize.x+size.x-client_size.x,
629 minSize.y+size.y-client_size.y );
630}
631
632// Return a window size that will fit within the screens dimensions
633wxSize wxSizer::FitSize( wxWindow *window )
634{
635 wxSize size = GetMinWindowSize( window );
636 wxSize sizeMax = GetMaxWindowSize( window );
637
638 // Limit the size if sizeMax != wxDefaultSize
639
640 if ( size.x > sizeMax.x && sizeMax.x != -1 )
641 size.x = sizeMax.x;
642 if ( size.y > sizeMax.y && sizeMax.y != -1 )
643 size.y = sizeMax.y;
644
645 return size;
646}
647
648wxSize wxSizer::GetMaxClientSize( wxWindow *window ) const
649{
650 wxSize maxSize( window->GetMaxSize() );
651
652 if( maxSize != wxDefaultSize )
653 {
654 wxSize size( window->GetSize() );
655 wxSize client_size( window->GetClientSize() );
656
657 return wxSize( maxSize.x + client_size.x - size.x,
658 maxSize.y + client_size.y - size.y );
659 }
660 else
661 return wxDefaultSize;
662}
663
664wxSize wxSizer::GetMinClientSize( wxWindow *WXUNUSED(window) )
665{
666 return GetMinSize(); // Already returns client size.
667}
668
669wxSize wxSizer::VirtualFitSize( wxWindow *window )
670{
671 wxSize size = GetMinClientSize( window );
672 wxSize sizeMax = GetMaxClientSize( window );
673
674 // Limit the size if sizeMax != wxDefaultSize
675
676 if ( size.x > sizeMax.x && sizeMax.x != -1 )
677 size.x = sizeMax.x;
678 if ( size.y > sizeMax.y && sizeMax.y != -1 )
679 size.y = sizeMax.y;
680
681 return size;
682}
683
684void wxSizer::SetDimension( int x, int y, int width, int height )
685{
686 m_position.x = x;
687 m_position.y = y;
688 m_size.x = width;
689 m_size.y = height;
690 Layout();
691}
692
693wxSize wxSizer::GetMinSize()
694{
695 wxSize ret( CalcMin() );
696 if (ret.x < m_minSize.x) ret.x = m_minSize.x;
697 if (ret.y < m_minSize.y) ret.y = m_minSize.y;
698 return ret;
699}
700
701void wxSizer::DoSetMinSize( int width, int height )
702{
703 m_minSize.x = width;
704 m_minSize.y = height;
705}
706
707bool wxSizer::DoSetItemMinSize( wxWindow *window, int width, int height )
708{
709 wxASSERT_MSG( window, _T("SetMinSize for NULL window") );
710
711 // Is it our immediate child?
712
713 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
714 while (node)
715 {
716 wxSizerItem *item = node->GetData();
717
718 if (item->GetWindow() == window)
719 {
720 item->SetInitSize( width, height );
721 return true;
722 }
723 node = node->GetNext();
724 }
725
726 // No? Search any subsizers we own then
727
728 node = m_children.GetFirst();
729 while (node)
730 {
731 wxSizerItem *item = node->GetData();
732
733 if ( item->GetSizer() &&
734 item->GetSizer()->DoSetItemMinSize( window, width, height ) )
735 {
736 // A child sizer found the requested windw, exit.
737 return true;
738 }
739 node = node->GetNext();
740 }
741
742 return false;
743}
744
745bool wxSizer::DoSetItemMinSize( wxSizer *sizer, int width, int height )
746{
747 wxASSERT_MSG( sizer, _T("SetMinSize for NULL sizer") );
748
749 // Is it our immediate child?
750
751 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
752 while (node)
753 {
754 wxSizerItem *item = node->GetData();
755
756 if (item->GetSizer() == sizer)
757 {
758 item->GetSizer()->DoSetMinSize( width, height );
759 return true;
760 }
761 node = node->GetNext();
762 }
763
764 // No? Search any subsizers we own then
765
766 node = m_children.GetFirst();
767 while (node)
768 {
769 wxSizerItem *item = node->GetData();
770
771 if ( item->GetSizer() &&
772 item->GetSizer()->DoSetItemMinSize( sizer, width, height ) )
773 {
774 // A child found the requested sizer, exit.
775 return true;
776 }
777 node = node->GetNext();
778 }
779
780 return false;
781}
782
783bool wxSizer::DoSetItemMinSize( size_t index, int width, int height )
784{
785 wxSizerItemList::compatibility_iterator node = m_children.Item( index );
786
787 wxCHECK_MSG( node, false, _T("Failed to find child node") );
788
789 wxSizerItem *item = node->GetData();
790
791 if (item->GetSizer())
792 {
793 // Sizers contains the minimal size in them, if not calculated ...
794 item->GetSizer()->DoSetMinSize( width, height );
795 }
796 else
797 {
798 // ... but the minimal size of spacers and windows in stored in them
799 item->SetInitSize( width, height );
800 }
801
802 return true;
803}
804
805void wxSizer::Show( wxWindow *window, bool show )
806{
807 wxASSERT_MSG( window, _T("Show for NULL window") );
808
809 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
810 while (node)
811 {
812 wxSizerItem *item = node->GetData();
813
814 if (item->GetWindow() == window)
815 {
816 item->Show( show );
817 break;
818 }
819 node = node->GetNext();
820 }
821}
822
823void wxSizer::Show( wxSizer *sizer, bool show )
824{
825 wxASSERT_MSG( sizer, _T("Show for NULL sizer") );
826
827 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
828 while (node)
829 {
830 wxSizerItem *item = node->GetData();
831
832 if (item->GetSizer() == sizer)
833 {
834 item->Show( show );
835 break;
836 }
837 node = node->GetNext();
838 }
839}
840
841void wxSizer::Show( size_t index, bool show )
842{
843 wxCHECK_RET( index < m_children.GetCount(),
844 _T("Show index is out of range") );
845
846 m_children.Item( index )->GetData()->Show( show );
847}
848
849void wxSizer::ShowItems( bool show )
850{
851 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
852 while (node)
853 {
854 node->GetData()->Show( show );
855 node = node->GetNext();
856 }
857}
858
859bool wxSizer::IsShown( wxWindow *window ) const
860{
861 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
862 while (node)
863 {
864 wxSizerItem *item = node->GetData();
865
866 if (item->GetWindow() == window)
867 {
868 return item->IsShown();
869 }
870 node = node->GetNext();
871 }
872
873 wxFAIL_MSG( _T("IsShown failed to find sizer item") );
874
875 return false;
876}
877
878bool wxSizer::IsShown( wxSizer *sizer ) const
879{
880 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
881 while (node)
882 {
883 wxSizerItem *item = node->GetData();
884
885 if (item->GetSizer() == sizer)
886 {
887 return item->IsShown();
888 }
889 node = node->GetNext();
890 }
891
892 wxFAIL_MSG( _T("IsShown failed to find sizer item") );
893
894 return false;
895}
896
897bool wxSizer::IsShown( size_t index ) const
898{
899 wxCHECK_MSG( index < m_children.GetCount(),
900 false,
901 _T("IsShown index is out of range") );
902
903 return m_children.Item( index )->GetData()->IsShown();
904}
905
906
907//---------------------------------------------------------------------------
908// wxGridSizer
909//---------------------------------------------------------------------------
910
911wxGridSizer::wxGridSizer( int rows, int cols, int vgap, int hgap )
912 : m_rows( rows )
913 , m_cols( cols )
914 , m_vgap( vgap )
915 , m_hgap( hgap )
916{
917}
918
919wxGridSizer::wxGridSizer( int cols, int vgap, int hgap )
920 : m_rows( 0 )
921 , m_cols( cols )
922 , m_vgap( vgap )
923 , m_hgap( hgap )
924{
925}
926
927int wxGridSizer::CalcRowsCols(int& nrows, int& ncols) const
928{
929 int nitems = m_children.GetCount();
930 if ( nitems)
931 {
932 if ( m_cols )
933 {
934 ncols = m_cols;
935 nrows = (nitems + m_cols - 1) / m_cols;
936 }
937 else if ( m_rows )
938 {
939 ncols = (nitems + m_rows - 1) / m_rows;
940 nrows = m_rows;
941 }
942 else // 0 columns, 0 rows?
943 {
944 wxFAIL_MSG( _T("grid sizer must have either rows or columns fixed") );
945
946 nrows = ncols = 0;
947 }
948 }
949
950 return nitems;
951}
952
953void wxGridSizer::RecalcSizes()
954{
955 int nitems, nrows, ncols;
956 if ( (nitems = CalcRowsCols(nrows, ncols)) == 0 )
957 return;
958
959 wxSize sz( GetSize() );
960 wxPoint pt( GetPosition() );
961
962 int w = (sz.x - (ncols - 1) * m_hgap) / ncols;
963 int h = (sz.y - (nrows - 1) * m_vgap) / nrows;
964
965 int x = pt.x;
966 for (int c = 0; c < ncols; c++)
967 {
968 int y = pt.y;
969 for (int r = 0; r < nrows; r++)
970 {
971 int i = r * ncols + c;
972 if (i < nitems)
973 {
974 wxSizerItemList::compatibility_iterator node = m_children.Item( i );
975
976 wxASSERT_MSG( node, _T("Failed to find SizerItemList node") );
977
978 SetItemBounds( node->GetData(), x, y, w, h);
979 }
980 y = y + h + m_vgap;
981 }
982 x = x + w + m_hgap;
983 }
984}
985
986wxSize wxGridSizer::CalcMin()
987{
988 int nrows, ncols;
989 if ( CalcRowsCols(nrows, ncols) == 0 )
990 return wxSize(10, 10);
991
992 // Find the max width and height for any component
993 int w = 0;
994 int h = 0;
995
996 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
997 while (node)
998 {
999 wxSizerItem *item = node->GetData();
1000 wxSize sz( item->CalcMin() );
1001
1002 w = wxMax( w, sz.x );
1003 h = wxMax( h, sz.y );
1004
1005 node = node->GetNext();
1006 }
1007
1008 return wxSize( ncols * w + (ncols-1) * m_hgap,
1009 nrows * h + (nrows-1) * m_vgap );
1010}
1011
1012void wxGridSizer::SetItemBounds( wxSizerItem *item, int x, int y, int w, int h )
1013{
1014 wxPoint pt( x,y );
1015 wxSize sz( item->CalcMin() );
1016 int flag = item->GetFlag();
1017
1018 if ((flag & wxEXPAND) || (flag & wxSHAPED))
1019 {
1020 sz = wxSize(w, h);
1021 }
1022 else
1023 {
1024 if (flag & wxALIGN_CENTER_HORIZONTAL)
1025 {
1026 pt.x = x + (w - sz.x) / 2;
1027 }
1028 else if (flag & wxALIGN_RIGHT)
1029 {
1030 pt.x = x + (w - sz.x);
1031 }
1032
1033 if (flag & wxALIGN_CENTER_VERTICAL)
1034 {
1035 pt.y = y + (h - sz.y) / 2;
1036 }
1037 else if (flag & wxALIGN_BOTTOM)
1038 {
1039 pt.y = y + (h - sz.y);
1040 }
1041 }
1042
1043 item->SetDimension(pt, sz);
1044}
1045
1046//---------------------------------------------------------------------------
1047// wxFlexGridSizer
1048//---------------------------------------------------------------------------
1049
1050wxFlexGridSizer::wxFlexGridSizer( int rows, int cols, int vgap, int hgap )
1051 : wxGridSizer( rows, cols, vgap, hgap ),
1052 m_flexDirection(wxBOTH),
1053 m_growMode(wxFLEX_GROWMODE_SPECIFIED)
1054{
1055}
1056
1057wxFlexGridSizer::wxFlexGridSizer( int cols, int vgap, int hgap )
1058 : wxGridSizer( cols, vgap, hgap ),
1059 m_flexDirection(wxBOTH),
1060 m_growMode(wxFLEX_GROWMODE_SPECIFIED)
1061{
1062}
1063
1064wxFlexGridSizer::~wxFlexGridSizer()
1065{
1066}
1067
1068void wxFlexGridSizer::RecalcSizes()
1069{
1070 int nitems, nrows, ncols;
1071 if ( (nitems = CalcRowsCols(nrows, ncols)) == 0 )
1072 return;
1073
1074 wxSize sz( GetSize() );
1075 wxSize minsz( CalcMin() );
1076 wxPoint pt( GetPosition() );
1077
1078 // what to do with the rows? by default, resize them proportionally
1079 if ( sz.y > minsz.y && ( (m_flexDirection & wxVERTICAL) || (m_growMode == wxFLEX_GROWMODE_SPECIFIED) ) )
1080 {
1081 int sum_proportions = 0;
1082 int growable_space = 0;
1083 int num = 0;
1084 size_t idx;
1085 for (idx = 0; idx < m_growableRows.GetCount(); idx++)
1086 {
1087 // Since the number of rows/columns can change as items are inserted/deleted, we need
1088 // to verify at runtime that the requested growable rows/columns are still valid.
1089 if (m_growableRows[idx] >= nrows)
1090 continue;
1091 // If all items in a row/column are hidden, that row/column will have a dimension of -1.
1092 // This causes the row/column to be hidden completely.
1093 if (m_rowHeights[ m_growableRows[idx] ] == -1)
1094 continue;
1095 sum_proportions += m_growableRowsProportions[idx];
1096 growable_space += m_rowHeights[ m_growableRows[idx] ];
1097 num++;
1098 }
1099
1100 if (num > 0)
1101 {
1102 for (idx = 0; idx < m_growableRows.GetCount(); idx++)
1103 {
1104 if (m_growableRows[idx] >= nrows )
1105 continue;
1106 if (m_rowHeights[ m_growableRows[idx] ] == -1)
1107 m_rowHeights[ m_growableRows[idx] ] = 0;
1108 else
1109 {
1110 int delta = (sz.y - minsz.y);
1111 if (sum_proportions == 0)
1112 delta = (delta/num) + m_rowHeights[ m_growableRows[idx] ];
1113 else
1114 delta = ((delta+growable_space)*m_growableRowsProportions[idx]) / sum_proportions;
1115 m_rowHeights[ m_growableRows[idx] ] = delta;
1116 }
1117 }
1118 }
1119 }
1120 else if ( (m_growMode == wxFLEX_GROWMODE_ALL) && (sz.y > minsz.y) )
1121 {
1122 // rounding problem?
1123 for ( int row = 0; row < nrows; ++row )
1124 m_rowHeights[ row ] = sz.y / nrows;
1125 }
1126
1127 // the same logic as above but for the columns
1128 if ( sz.x > minsz.x && ( (m_flexDirection & wxHORIZONTAL) || (m_growMode == wxFLEX_GROWMODE_SPECIFIED) ) )
1129 {
1130 int sum_proportions = 0;
1131 int growable_space = 0;
1132 int num = 0;
1133 size_t idx;
1134 for (idx = 0; idx < m_growableCols.GetCount(); idx++)
1135 {
1136 // Since the number of rows/columns can change as items are inserted/deleted, we need
1137 // to verify at runtime that the requested growable rows/columns are still valid.
1138 if (m_growableCols[idx] >= ncols)
1139 continue;
1140 // If all items in a row/column are hidden, that row/column will have a dimension of -1.
1141 // This causes the column to be hidden completely.
1142 if (m_colWidths[ m_growableCols[idx] ] == -1)
1143 continue;
1144 sum_proportions += m_growableColsProportions[idx];
1145 // wtb 5/12/02 bugfix - was m_ColWidths[idx]!!
1146 growable_space += m_colWidths[ m_growableCols[idx] ];
1147 num++;
1148 }
1149
1150 if (num > 0)
1151 {
1152 for (idx = 0; idx < m_growableCols.GetCount(); idx++)
1153 {
1154 if (m_growableCols[idx] >= ncols )
1155 continue;
1156 if (m_colWidths[ m_growableCols[idx] ] == -1)
1157 m_colWidths[ m_growableCols[idx] ] = 0;
1158 else
1159 {
1160 int delta = (sz.x - minsz.x);
1161 if (sum_proportions == 0)
1162 delta = (delta/num) + m_colWidths[ m_growableCols[idx] ];
1163 else
1164 delta = ((delta+growable_space)*m_growableColsProportions[idx])/sum_proportions;
1165 m_colWidths[ m_growableCols[idx] ] = delta;
1166 }
1167 }
1168 }
1169 }
1170 else if ( (m_growMode == wxFLEX_GROWMODE_ALL) && (sz.x > minsz.x) )
1171 {
1172 for ( int col=0; col < ncols; ++col )
1173 m_colWidths[ col ] = sz.x / ncols;
1174 }
1175
1176 sz = wxSize( pt.x + sz.x, pt.y + sz.y );
1177
1178 int x = pt.x;
1179 for (int c = 0; c < ncols; c++)
1180 {
1181 int y = pt.y;
1182 for (int r = 0; r < nrows; r++)
1183 {
1184 int i = r * ncols + c;
1185 if (i < nitems)
1186 {
1187 wxSizerItemList::compatibility_iterator node = m_children.Item( i );
1188
1189 wxASSERT_MSG( node, _T("Failed to find node") );
1190
1191 int w = wxMax( 0, wxMin( m_colWidths[c], sz.x - x ) );
1192 int h = wxMax( 0, wxMin( m_rowHeights[r], sz.y - y ) );
1193
1194 SetItemBounds( node->GetData(), x, y, w, h);
1195 }
1196 y = y + m_rowHeights[r] + m_vgap;
1197 }
1198 x = x + m_colWidths[c] + m_hgap;
1199 }
1200}
1201
1202wxSize wxFlexGridSizer::CalcMin()
1203{
1204 int nrows,
1205 ncols;
1206 size_t i, s;
1207
1208 // Number of rows/columns can change as items are added or removed.
1209 if ( !CalcRowsCols(nrows, ncols) )
1210 return wxSize(10, 10);
1211
1212 m_rowHeights.SetCount(nrows);
1213 m_colWidths.SetCount(ncols);
1214
1215 // We have to recalcuate the sizes in case an item has wxADJUST_MINSIZE, has changed
1216 // minimum size since the previous layout, or has been hidden using wxSizer::Show().
1217 // If all the items in a row/column are hidden, the final dimension of the row/column
1218 // will be -1, indicating that the column itself is hidden.
1219 for( s = m_rowHeights.GetCount(), i = 0; i < s; ++i )
1220 m_rowHeights[ i ] = -1;
1221 for( s = m_colWidths.GetCount(), i = 0; i < s; ++i )
1222 m_colWidths[ i ] = -1;
1223
1224 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
1225
1226 i = 0;
1227 while (node)
1228 {
1229 wxSizerItem *item = node->GetData();
1230 if ( item->IsShown() )
1231 {
1232 wxSize sz( item->CalcMin() );
1233 int row = i / ncols;
1234 int col = i % ncols;
1235
1236 m_rowHeights[ row ] = wxMax( wxMax( 0, sz.y ), m_rowHeights[ row ] );
1237 m_colWidths[ col ] = wxMax( wxMax( 0, sz.x ), m_colWidths[ col ] );
1238 }
1239
1240 node = node->GetNext();
1241 i++;
1242 }
1243
1244 // the logic above works when we resize flexibly in both directions but
1245 // maybe this is not the case
1246 if ( m_flexDirection != wxBOTH )
1247 {
1248 // select the array corresponding to the direction in which we do *not*
1249 // resize flexibly
1250 wxArrayInt& array = m_flexDirection == wxVERTICAL ? m_colWidths
1251 : m_rowHeights;
1252
1253 const int count = array.GetCount();
1254
1255 // find the largest value in this array
1256 int n, largest = 0;
1257 for ( n = 0; n < count; ++n )
1258 {
1259 if ( array[n] > largest )
1260 largest = array[n];
1261 }
1262
1263 // and now fill it with the largest value
1264 for ( n = 0; n < count; ++n )
1265 {
1266 array[n] = largest;
1267 }
1268 }
1269
1270 // Sum total minimum size, including gaps between rows/columns.
1271 // -1 is used as a magic number meaning empty column.
1272 int width = 0;
1273 for (int col = 0; col < ncols; col++)
1274 if ( m_colWidths[ col ] != -1 )
1275 width += m_colWidths[ col ] + ( col == ncols-1 ? 0 : m_hgap );
1276
1277 int height = 0;
1278 for (int row = 0; row < nrows; row++)
1279 if ( m_rowHeights[ row ] != -1 )
1280 height += m_rowHeights[ row ] + ( row == nrows-1 ? 0 : m_vgap );
1281
1282 return wxSize( width, height );
1283}
1284
1285void wxFlexGridSizer::AddGrowableRow( size_t idx, int proportion )
1286{
1287 m_growableRows.Add( idx );
1288 m_growableRowsProportions.Add( proportion );
1289}
1290
1291void wxFlexGridSizer::RemoveGrowableRow( size_t WXUNUSED(idx) )
1292{
1293}
1294
1295void wxFlexGridSizer::AddGrowableCol( size_t idx, int proportion )
1296{
1297 m_growableCols.Add( idx );
1298 m_growableColsProportions.Add( proportion );
1299}
1300
1301void wxFlexGridSizer::RemoveGrowableCol( size_t WXUNUSED(idx) )
1302{
1303}
1304
1305//---------------------------------------------------------------------------
1306// wxBoxSizer
1307//---------------------------------------------------------------------------
1308
1309wxBoxSizer::wxBoxSizer( int orient )
1310 : m_orient( orient )
1311{
1312}
1313
1314void wxBoxSizer::RecalcSizes()
1315{
1316 if (m_children.GetCount() == 0)
1317 return;
1318
1319 int delta = 0;
1320 if (m_stretchable)
1321 {
1322 if (m_orient == wxHORIZONTAL)
1323 delta = m_size.x - m_fixedWidth;
1324 else
1325 delta = m_size.y - m_fixedHeight;
1326 }
1327
1328 wxPoint pt( m_position );
1329
1330 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
1331 while (node)
1332 {
1333 wxSizerItem *item = node->GetData();
1334
1335 if (item->IsShown())
1336 {
1337 wxSize size( item->CalcMin() );
1338
1339 if (m_orient == wxVERTICAL)
1340 {
1341 wxCoord height = size.y;
1342 if (item->GetProportion())
1343 {
1344 // Because of at least one visible item has non-zero
1345 // proportion then m_stretchable is not zero
1346 height = (delta * item->GetProportion()) / m_stretchable;
1347 }
1348
1349 wxPoint child_pos( pt );
1350 wxSize child_size( wxSize( size.x, height) );
1351
1352 if (item->GetFlag() & (wxEXPAND | wxSHAPED))
1353 child_size.x = m_size.x;
1354 else if (item->GetFlag() & wxALIGN_RIGHT)
1355 child_pos.x += m_size.x - size.x;
1356 else if (item->GetFlag() & (wxCENTER | wxALIGN_CENTER_HORIZONTAL))
1357 // XXX wxCENTER is added for backward compatibility;
1358 // wxALIGN_CENTER should be used in new code
1359 child_pos.x += (m_size.x - size.x) / 2;
1360
1361 item->SetDimension( child_pos, child_size );
1362
1363 pt.y += height;
1364 }
1365 else
1366 {
1367 wxCoord width = size.x;
1368 if (item->GetProportion())
1369 {
1370 // Because of at least one visible item has non-zero
1371 // proportion then m_stretchable is not zero
1372 width = (delta * item->GetProportion()) / m_stretchable;
1373 }
1374
1375 wxPoint child_pos( pt );
1376 wxSize child_size( wxSize(width, size.y) );
1377
1378 if (item->GetFlag() & (wxEXPAND | wxSHAPED))
1379 child_size.y = m_size.y;
1380 else if (item->GetFlag() & wxALIGN_BOTTOM)
1381 child_pos.y += m_size.y - size.y;
1382 else if (item->GetFlag() & (wxCENTER | wxALIGN_CENTER_VERTICAL))
1383 // XXX wxCENTER is added for backward compatibility;
1384 // wxALIGN_CENTER should be used in new code
1385 child_pos.y += (m_size.y - size.y) / 2;
1386
1387 item->SetDimension( child_pos, child_size );
1388
1389 pt.x += width;
1390 }
1391 }
1392
1393 node = node->GetNext();
1394 }
1395}
1396
1397wxSize wxBoxSizer::CalcMin()
1398{
1399 if (m_children.GetCount() == 0)
1400 return wxSize(10,10);
1401
1402 m_stretchable = 0;
1403 m_minWidth = 0;
1404 m_minHeight = 0;
1405 m_fixedWidth = 0;
1406 m_fixedHeight = 0;
1407
1408 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
1409 while (node)
1410 {
1411 wxSizerItem *item = node->GetData();
1412
1413 if (item->IsShown() && item->GetProportion() != 0)
1414 m_stretchable += item->GetProportion();
1415
1416 node = node->GetNext();
1417 }
1418
1419 // Total minimum size (width or height) of sizer
1420 int maxMinSize = 0;
1421
1422 node = m_children.GetFirst();
1423 while (node)
1424 {
1425 wxSizerItem *item = node->GetData();
1426
1427 if (item->IsShown() && item->GetProportion() != 0)
1428 {
1429 int stretch = item->GetProportion();
1430 wxSize size( item->CalcMin() );
1431 int minSize;
1432
1433 // Integer division rounded up is (a + b - 1) / b
1434 // Round up needed in order to guarantee that all
1435 // all items will have size not less then their min size
1436 if (m_orient == wxHORIZONTAL)
1437 minSize = ( size.x*m_stretchable + stretch - 1)/stretch;
1438 else
1439 minSize = ( size.y*m_stretchable + stretch - 1)/stretch;
1440
1441 if (minSize > maxMinSize)
1442 maxMinSize = minSize;
1443 }
1444 node = node->GetNext();
1445 }
1446
1447 // Calculate overall minimum size
1448 node = m_children.GetFirst();
1449 while (node)
1450 {
1451 wxSizerItem *item = node->GetData();
1452
1453 if (item->IsShown())
1454 {
1455 wxSize size( item->CalcMin() );
1456 if (item->GetProportion() != 0)
1457 {
1458 if (m_orient == wxHORIZONTAL)
1459 size.x = (maxMinSize*item->GetProportion())/m_stretchable;
1460 else
1461 size.y = (maxMinSize*item->GetProportion())/m_stretchable;
1462 }
1463 else
1464 {
1465 if (m_orient == wxVERTICAL)
1466 {
1467 m_fixedHeight += size.y;
1468 m_fixedWidth = wxMax( m_fixedWidth, size.x );
1469 }
1470 else
1471 {
1472 m_fixedWidth += size.x;
1473 m_fixedHeight = wxMax( m_fixedHeight, size.y );
1474 }
1475 }
1476
1477 if (m_orient == wxHORIZONTAL)
1478 {
1479 m_minWidth += size.x;
1480 m_minHeight = wxMax( m_minHeight, size.y );
1481 }
1482 else
1483 {
1484 m_minHeight += size.y;
1485 m_minWidth = wxMax( m_minWidth, size.x );
1486 }
1487 }
1488 node = node->GetNext();
1489 }
1490
1491 return wxSize( m_minWidth, m_minHeight );
1492}
1493
1494//---------------------------------------------------------------------------
1495// wxStaticBoxSizer
1496//---------------------------------------------------------------------------
1497
1498#if wxUSE_STATBOX
1499
1500wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox *box, int orient )
1501 : wxBoxSizer( orient )
1502 , m_staticBox( box )
1503{
1504 wxASSERT_MSG( box, wxT("wxStaticBoxSizer needs a static box") );
1505}
1506
1507static void GetStaticBoxBorders( wxStaticBox *box,
1508 int *borderTop,
1509 int *borderOther)
1510{
1511 // this has to be done platform by platform as there is no way to
1512 // guess the thickness of a wxStaticBox border
1513#ifdef __WXCOCOA__
1514 box->GetBordersForSizer(borderTop,borderOther);
1515#else // __WXCOCOA__
1516#ifdef __WXGTK__
1517 if ( box->GetLabel().IsEmpty() )
1518 *borderTop = 5;
1519 else
1520#endif // __WXGTK__
1521 *borderTop = box->GetCharHeight();
1522
1523 *borderOther = 5;
1524#endif // __WXCOCOA__
1525}
1526
1527void wxStaticBoxSizer::RecalcSizes()
1528{
1529 int top_border, other_border;
1530 GetStaticBoxBorders(m_staticBox, &top_border, &other_border);
1531
1532 m_staticBox->SetSize( m_position.x, m_position.y, m_size.x, m_size.y );
1533
1534 wxPoint old_pos( m_position );
1535 m_position.x += other_border;
1536 m_position.y += top_border;
1537 wxSize old_size( m_size );
1538 m_size.x -= 2*other_border;
1539 m_size.y -= top_border + other_border;
1540
1541 wxBoxSizer::RecalcSizes();
1542
1543 m_position = old_pos;
1544 m_size = old_size;
1545}
1546
1547wxSize wxStaticBoxSizer::CalcMin()
1548{
1549 int top_border, other_border;
1550 GetStaticBoxBorders(m_staticBox, &top_border, &other_border);
1551
1552 wxSize ret( wxBoxSizer::CalcMin() );
1553 ret.x += 2*other_border;
1554 ret.y += other_border + top_border;
1555
1556 return ret;
1557}
1558
1559#endif // wxUSE_STATBOX
1560
1561// ----------------------------------------------------------------------------
1562// wxNotebookSizer
1563// ----------------------------------------------------------------------------
1564
1565#if wxUSE_BOOKCTRL
1566
1567wxBookCtrlSizer::wxBookCtrlSizer(wxBookCtrl *bookctrl)
1568 : m_bookctrl(bookctrl)
1569{
1570 wxASSERT_MSG( bookctrl, wxT("wxBookCtrlSizer needs a control") );
1571}
1572
1573void wxBookCtrlSizer::RecalcSizes()
1574{
1575 m_bookctrl->SetSize( m_position.x, m_position.y, m_size.x, m_size.y );
1576}
1577
1578wxSize wxBookCtrlSizer::CalcMin()
1579{
1580 wxSize sizeBorder = m_bookctrl->CalcSizeFromPage(wxSize(0, 0));
1581
1582 sizeBorder.x += 5;
1583 sizeBorder.y += 5;
1584
1585 if ( m_bookctrl->GetPageCount() == 0 )
1586 {
1587 return wxSize(sizeBorder.x + 10, sizeBorder.y + 10);
1588 }
1589
1590 int maxX = 0;
1591 int maxY = 0;
1592
1593 wxWindowList::compatibility_iterator
1594 node = m_bookctrl->GetChildren().GetFirst();
1595 while (node)
1596 {
1597 wxWindow *item = node->GetData();
1598 wxSizer *itemsizer = item->GetSizer();
1599
1600 if (itemsizer)
1601 {
1602 wxSize subsize( itemsizer->CalcMin() );
1603
1604 if (subsize.x > maxX)
1605 maxX = subsize.x;
1606 if (subsize.y > maxY)
1607 maxY = subsize.y;
1608 }
1609
1610 node = node->GetNext();
1611 }
1612
1613 return wxSize( maxX, maxY ) + sizeBorder;
1614}
1615
1616
1617#if wxUSE_NOTEBOOK
1618
1619wxNotebookSizer::wxNotebookSizer(wxNotebook *nb)
1620 : wxBookCtrlSizer(nb)
1621{
1622}
1623
1624#endif // wxUSE_NOTEBOOOK
1625#endif // wxUSE_BOOKCTRL
1626