]> git.saurik.com Git - wxWidgets.git/blame - src/common/sizer.cpp
wxMSWUniv wxWindowMSW vs. wxWindow fix.
[wxWidgets.git] / src / common / sizer.cpp
CommitLineData
5279a24d
RR
1/////////////////////////////////////////////////////////////////////////////
2// Name: sizer.cpp
1044a386 3// Purpose: provide new wxSizer class for layout
aa5973ee
JS
4// Author: Robert Roebling and Robin Dunn, contributions by
5// Dirk Holtwick, Ron Lee
566d84a7 6// Modified by: Ron Lee
0c0d686f 7// Created:
5279a24d 8// RCS-ID: $Id$
aa5973ee 9// Copyright: (c) Robin Dunn, Robert Roebling
65571936 10// Licence: wxWindows licence
5279a24d
RR
11/////////////////////////////////////////////////////////////////////////////
12
14f355c2 13#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
c62ac5b6 14#pragma implementation "sizer.h"
5279a24d
RR
15#endif
16
77671fd2
VZ
17// For compilers that support precompilation, includes "wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
21 #pragma hdrstop
22#endif
23
5279a24d 24#include "wx/sizer.h"
61d514bb 25#include "wx/utils.h"
27ea1d8a 26#include "wx/statbox.h"
acf2ac37 27#include "wx/settings.h"
c54b92d3 28#include "wx/listimpl.cpp"
adbf2d73
VS
29#if WXWIN_COMPATIBILITY_2_4
30 #include "wx/notebook.h"
31#endif
5279a24d 32
78ca5669
DS
33#ifdef __WXMAC__
34# include "wx/mac/uma.h"
35#endif
36
0c0d686f
RD
37//---------------------------------------------------------------------------
38
9cbee2ce
RL
39IMPLEMENT_CLASS(wxSizerItem, wxObject)
40IMPLEMENT_CLASS(wxSizer, wxObject)
41IMPLEMENT_CLASS(wxGridSizer, wxSizer)
42IMPLEMENT_CLASS(wxFlexGridSizer, wxGridSizer)
43IMPLEMENT_CLASS(wxBoxSizer, wxSizer)
1e6feb95 44#if wxUSE_STATBOX
9cbee2ce 45IMPLEMENT_CLASS(wxStaticBoxSizer, wxBoxSizer)
1e6feb95 46#endif
974c2a59 47#if wxUSE_BUTTON
acf2ac37 48IMPLEMENT_CLASS(wxStdDialogButtonSizer, wxBoxSizer)
974c2a59 49#endif
0c0d686f 50
12a3f227
RL
51WX_DEFINE_EXPORTED_LIST( wxSizerItemList );
52
066f1b7a 53/*
8b2bac62
WS
54 TODO PROPERTIES
55 sizeritem
56 object
57 object_ref
58 minsize
59 option
60 flag
61 border
066f1b7a 62 spacer
8b2bac62
WS
63 option
64 flag
65 borfder
66 boxsizer
67 orient
066f1b7a 68 staticboxsizer
8b2bac62
WS
69 orient
70 label
71 gridsizer
72 rows
73 cols
74 vgap
75 hgap
76 flexgridsizer
77 rows
78 cols
79 vgap
80 hgap
81 growablerows
82 growablecols
066f1b7a
SC
83 minsize
84*/
ccbc8038 85
5279a24d 86//---------------------------------------------------------------------------
3417c2cd 87// wxSizerItem
5279a24d
RR
88//---------------------------------------------------------------------------
89
ccbc8038
VZ
90void wxSizerItem::Init()
91{
92 m_window = NULL;
93 m_sizer = NULL;
94 m_show = true;
95 m_userData = NULL;
56eee37f 96 m_zoneRect = wxRect( 0, 0, 0, 0 );
ccbc8038
VZ
97}
98
99void wxSizerItem::Init(const wxSizerFlags& flags)
100{
101 Init();
102
103 m_proportion = flags.GetProportion();
104 m_flag = flags.GetFlags();
105 m_border = flags.GetBorderInPixels();
106}
107
12a3f227
RL
108wxSizerItem::wxSizerItem( int width, int height, int proportion, int flag, int border, wxObject* userData )
109 : m_window( NULL )
110 , m_sizer( NULL )
00976fe5
RL
111 , m_size( wxSize( width, height ) ) // size is set directly
112 , m_minSize( m_size ) // minimal size is the initial size
12a3f227 113 , m_proportion( proportion )
00976fe5
RL
114 , m_border( border )
115 , m_flag( flag )
56eee37f 116 , m_zoneRect( 0, 0, 0, 0 )
e0d8fb45 117 , m_show( true )
00976fe5 118 , m_userData( userData )
5279a24d 119{
00976fe5 120 SetRatio( m_size );
5279a24d
RR
121}
122
12a3f227 123wxSizerItem::wxSizerItem( wxWindow *window, int proportion, int flag, int border, wxObject* userData )
00976fe5 124 : m_window( window )
12a3f227 125 , m_sizer( NULL )
12a3f227 126 , m_proportion( proportion )
00976fe5
RL
127 , m_border( border )
128 , m_flag( flag )
56eee37f 129 , m_zoneRect( 0, 0, 0, 0 )
e0d8fb45 130 , m_show( true )
00976fe5 131 , m_userData( userData )
5279a24d 132{
ba763a45
RD
133 if (flag & wxFIXED_MINSIZE)
134 window->SetMinSize(window->GetSize());
135 m_minSize = window->GetSize();
8b2bac62 136
36461f58
RD
137 // aspect ratio calculated from initial size
138 SetRatio( m_minSize );
139
00976fe5 140 // m_size is calculated later
5279a24d
RR
141}
142
12a3f227
RL
143wxSizerItem::wxSizerItem( wxSizer *sizer, int proportion, int flag, int border, wxObject* userData )
144 : m_window( NULL )
00976fe5 145 , m_sizer( sizer )
12a3f227 146 , m_proportion( proportion )
00976fe5
RL
147 , m_border( border )
148 , m_flag( flag )
56eee37f 149 , m_zoneRect( 0, 0, 0, 0 )
e0d8fb45 150 , m_show( true )
12a3f227 151 , m_ratio( 0.0 )
00976fe5 152 , m_userData( userData )
5279a24d 153{
00976fe5
RL
154 // m_minSize is calculated later
155 // m_size is calculated later
5279a24d
RR
156}
157
20b35a69 158wxSizerItem::wxSizerItem()
20b35a69 159{
ccbc8038
VZ
160 Init();
161
162 m_proportion = 0;
163 m_border = 0;
164 m_flag = 0;
20b35a69
RD
165}
166
0c0d686f
RD
167wxSizerItem::~wxSizerItem()
168{
f91e8382
VZ
169 delete m_userData;
170
171 if ( m_window )
172 {
173 m_window->SetContainingSizer(NULL);
174 }
175 else // we must be a sizer
176 {
0c0d686f 177 delete m_sizer;
f91e8382 178 }
0c0d686f
RD
179}
180
181
9cbee2ce 182wxSize wxSizerItem::GetSize() const
5279a24d 183{
d597fcb7 184 wxSize ret;
3417c2cd 185 if (IsSizer())
d597fcb7
RR
186 ret = m_sizer->GetSize();
187 else
c62ac5b6 188 if (IsWindow())
d597fcb7
RR
189 ret = m_window->GetSize();
190 else ret = m_size;
0c0d686f 191
d597fcb7
RR
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;
0c0d686f 200
d597fcb7 201 return ret;
5279a24d
RR
202}
203
3417c2cd 204wxSize wxSizerItem::CalcMin()
c62ac5b6 205{
3417c2cd 206 if (IsSizer())
be2577e4 207 {
ba763a45 208 m_minSize = m_sizer->GetMinSize();
d13d8d4e 209
be2577e4
RD
210 // if we have to preserve aspect ratio _AND_ this is
211 // the first-time calculation, consider ret to be initial size
d13d8d4e 212 if ((m_flag & wxSHAPED) && !m_ratio)
36461f58 213 SetRatio(m_minSize);
be2577e4 214 }
ba763a45 215 else if ( IsWindow() )
d13d8d4e 216 {
ba763a45
RD
217 // Since the size of the window may change during runtime, we
218 // should use the current minimal/best size.
219 m_minSize = m_window->GetBestFittingSize();
d13d8d4e 220 }
0c0d686f 221
ba763a45
RD
222 return GetMinSizeWithBorder();
223}
224
225wxSize wxSizerItem::GetMinSizeWithBorder() const
226{
227 wxSize ret = m_minSize;
228
d597fcb7
RR
229 if (m_flag & wxWEST)
230 ret.x += m_border;
231 if (m_flag & wxEAST)
232 ret.x += m_border;
233 if (m_flag & wxNORTH)
234 ret.y += m_border;
235 if (m_flag & wxSOUTH)
236 ret.y += m_border;
8b2bac62 237
d597fcb7 238 return ret;
c62ac5b6
RR
239}
240
ba763a45 241
3417c2cd 242void wxSizerItem::SetDimension( wxPoint pos, wxSize size )
c62ac5b6 243{
cdddaeea 244 if (m_flag & wxSHAPED)
d597fcb7 245 {
be2577e4
RD
246 // adjust aspect ratio
247 int rwidth = (int) (size.y * m_ratio);
cdddaeea
VZ
248 if (rwidth > size.x)
249 {
be2577e4
RD
250 // fit horizontally
251 int rheight = (int) (size.x / m_ratio);
252 // add vertical space
253 if (m_flag & wxALIGN_CENTER_VERTICAL)
254 pos.y += (size.y - rheight) / 2;
255 else if (m_flag & wxALIGN_BOTTOM)
256 pos.y += (size.y - rheight);
257 // use reduced dimensions
258 size.y =rheight;
cdddaeea
VZ
259 }
260 else if (rwidth < size.x)
261 {
be2577e4
RD
262 // add horizontal space
263 if (m_flag & wxALIGN_CENTER_HORIZONTAL)
264 pos.x += (size.x - rwidth) / 2;
265 else if (m_flag & wxALIGN_RIGHT)
266 pos.x += (size.x - rwidth);
267 size.x = rwidth;
268 }
269 }
33ac7e6f 270
cdddaeea
VZ
271 // This is what GetPosition() returns. Since we calculate
272 // borders afterwards, GetPosition() will be the left/top
273 // corner of the surrounding border.
274 m_pos = pos;
275
276 if (m_flag & wxWEST)
277 {
278 pos.x += m_border;
279 size.x -= m_border;
280 }
281 if (m_flag & wxEAST)
282 {
283 size.x -= m_border;
284 }
285 if (m_flag & wxNORTH)
286 {
287 pos.y += m_border;
288 size.y -= m_border;
289 }
290 if (m_flag & wxSOUTH)
291 {
292 size.y -= m_border;
293 }
0c0d686f 294
3417c2cd 295 if (IsSizer())
c62ac5b6 296 m_sizer->SetDimension( pos.x, pos.y, size.x, size.y );
0c0d686f 297
56eee37f 298 m_zoneRect = wxRect(pos, size);
c62ac5b6 299 if (IsWindow())
b919f007 300 m_window->SetSize( pos.x, pos.y, size.x, size.y, wxSIZE_ALLOW_MINUS_ONE );
d597fcb7
RR
301
302 m_size = size;
c62ac5b6
RR
303}
304
84f7908b
RR
305void wxSizerItem::DeleteWindows()
306{
307 if (m_window)
77aa9abd 308 {
84f7908b 309 m_window->Destroy();
77aa9abd
RD
310 m_window = NULL;
311 }
be90c029 312
84f7908b
RR
313 if (m_sizer)
314 m_sizer->DeleteWindows();
315}
316
9cbee2ce 317bool wxSizerItem::IsWindow() const
5279a24d
RR
318{
319 return (m_window != NULL);
320}
321
9cbee2ce 322bool wxSizerItem::IsSizer() const
5279a24d
RR
323{
324 return (m_sizer != NULL);
325}
326
9cbee2ce 327bool wxSizerItem::IsSpacer() const
5279a24d
RR
328{
329 return (m_window == NULL) && (m_sizer == NULL);
330}
331
12a3f227
RL
332void wxSizerItem::Show( bool show )
333{
334 m_show = show;
335
336 if( IsWindow() )
337 m_window->Show( show );
338 else if( IsSizer() )
339 m_sizer->ShowItems( show );
340
341 // ... nothing else to do to hide/show spacers
342}
343
344void wxSizerItem::SetOption( int option )
345{
346 SetProportion( option );
347}
348
349int wxSizerItem::GetOption() const
350{
351 return GetProportion();
352}
353
354
5279a24d 355//---------------------------------------------------------------------------
3417c2cd 356// wxSizer
5279a24d
RR
357//---------------------------------------------------------------------------
358
3417c2cd 359wxSizer::wxSizer()
12a3f227 360 : m_minSize( wxSize( 0, 0 ) )
5279a24d 361{
5279a24d
RR
362}
363
3417c2cd 364wxSizer::~wxSizer()
5279a24d 365{
222ed1d6 366 WX_CLEAR_LIST(wxSizerItemList, m_children);
5279a24d 367}
0c0d686f 368
56eee37f 369wxSizerItem* wxSizer::Insert( size_t index, wxSizerItem *item )
12a3f227
RL
370{
371 m_children.Insert( index, item );
0c0d686f 372
12a3f227
RL
373 if( item->GetWindow() )
374 item->GetWindow()->SetContainingSizer( this );
56eee37f
WS
375
376 return item;
12a3f227
RL
377}
378
379bool wxSizer::Remove( wxWindow *window )
380{
381 return Detach( window );
42b4e99e
RR
382}
383
384bool wxSizer::Remove( wxSizer *sizer )
385{
12a3f227 386 wxASSERT_MSG( sizer, _T("Removing NULL sizer") );
0c0d686f 387
222ed1d6 388 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
42b4e99e
RR
389 while (node)
390 {
12a3f227
RL
391 wxSizerItem *item = node->GetData();
392
3ca6a5f0 393 if (item->GetSizer() == sizer)
222ed1d6
MB
394 {
395 delete item;
396 m_children.Erase( node );
397 return true;
398 }
12a3f227
RL
399
400 node = node->GetNext();
42b4e99e 401 }
0c0d686f 402
e0d8fb45 403 return false;
42b4e99e
RR
404}
405
e0d8fb45 406bool wxSizer::Remove( int index )
42b4e99e 407{
e0d8fb45
VZ
408 wxCHECK_MSG( index >= 0 && (size_t)index < m_children.GetCount(),
409 false,
12a3f227 410 _T("Remove index is out of range") );
0c0d686f 411
222ed1d6 412 wxSizerItemList::compatibility_iterator node = m_children.Item( index );
0c0d686f 413
e0d8fb45 414 wxCHECK_MSG( node, false, _T("Failed to find child node") );
12a3f227 415
e0d8fb45 416 wxSizerItem *item = node->GetData();
9cbee2ce
RL
417
418 if( item->IsWindow() )
419 item->GetWindow()->SetContainingSizer( NULL );
420
222ed1d6
MB
421 delete item;
422 m_children.Erase( node );
423 return true;
42b4e99e 424}
0c0d686f 425
00976fe5
RL
426bool wxSizer::Detach( wxSizer *sizer )
427{
12a3f227 428 wxASSERT_MSG( sizer, _T("Detaching NULL sizer") );
00976fe5 429
222ed1d6 430 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
00976fe5
RL
431 while (node)
432 {
12a3f227
RL
433 wxSizerItem *item = node->GetData();
434
00976fe5
RL
435 if (item->GetSizer() == sizer)
436 {
96fdbb60 437 item->DetachSizer();
89c20ac1 438 delete item;
222ed1d6
MB
439 m_children.Erase( node );
440 return true;
12a3f227
RL
441 }
442 node = node->GetNext();
443 }
444
e0d8fb45 445 return false;
12a3f227
RL
446}
447
448bool wxSizer::Detach( wxWindow *window )
449{
450 wxASSERT_MSG( window, _T("Detaching NULL window") );
451
222ed1d6 452 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
12a3f227
RL
453 while (node)
454 {
455 wxSizerItem *item = node->GetData();
456
457 if (item->GetWindow() == window)
458 {
459 item->GetWindow()->SetContainingSizer( NULL );
89c20ac1 460 delete item;
222ed1d6
MB
461 m_children.Erase( node );
462 return true;
00976fe5 463 }
12a3f227 464 node = node->GetNext();
00976fe5
RL
465 }
466
e0d8fb45 467 return false;
00976fe5
RL
468}
469
e0d8fb45 470bool wxSizer::Detach( int index )
00976fe5 471{
e0d8fb45
VZ
472 wxCHECK_MSG( index >= 0 && (size_t)index < m_children.GetCount(),
473 false,
12a3f227
RL
474 _T("Detach index is out of range") );
475
222ed1d6 476 wxSizerItemList::compatibility_iterator node = m_children.Item( index );
00976fe5 477
e0d8fb45 478 wxCHECK_MSG( node, false, _T("Failed to find child node") );
00976fe5 479
e0d8fb45 480 wxSizerItem *item = node->GetData();
9cbee2ce
RL
481
482 if( item->IsSizer() )
483 item->DetachSizer();
484 else if( item->IsWindow() )
485 item->GetWindow()->SetContainingSizer( NULL );
12a3f227 486
89c20ac1 487 delete item;
222ed1d6
MB
488 m_children.Erase( node );
489 return true;
00976fe5
RL
490}
491
84f7908b
RR
492void wxSizer::Clear( bool delete_windows )
493{
be90c029 494 // First clear the ContainingSizer pointers
222ed1d6 495 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
be90c029
RD
496 while (node)
497 {
12a3f227
RL
498 wxSizerItem *item = node->GetData();
499
be90c029 500 if (item->IsWindow())
12a3f227
RL
501 item->GetWindow()->SetContainingSizer( NULL );
502 node = node->GetNext();
be90c029
RD
503 }
504
505 // Destroy the windows if needed
84f7908b
RR
506 if (delete_windows)
507 DeleteWindows();
be90c029
RD
508
509 // Now empty the list
222ed1d6 510 WX_CLEAR_LIST(wxSizerItemList, m_children);
84f7908b
RR
511}
512
513void wxSizer::DeleteWindows()
514{
222ed1d6 515 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
84f7908b
RR
516 while (node)
517 {
12a3f227
RL
518 wxSizerItem *item = node->GetData();
519
84f7908b 520 item->DeleteWindows();
12a3f227 521 node = node->GetNext();
84f7908b
RR
522 }
523}
524
e5251d4f 525wxSize wxSizer::Fit( wxWindow *window )
5279a24d 526{
f43c7771
VZ
527 wxSize size(window->IsTopLevel() ? FitSize(window)
528 : GetMinWindowSize(window));
9ef2e675 529
ccf5c8a8 530 window->SetSize( size );
e5251d4f
VZ
531
532 return size;
5279a24d
RR
533}
534
566d84a7
RL
535void wxSizer::FitInside( wxWindow *window )
536{
537 wxSize size;
538 if (window->IsTopLevel())
539 size = VirtualFitSize( window );
540 else
541 size = GetMinClientSize( window );
542
543 window->SetVirtualSize( size );
544}
545
3417c2cd 546void wxSizer::Layout()
c62ac5b6 547{
ba763a45
RD
548 // (re)calculates minimums needed for each item and other preparations
549 // for layout
42b4e99e 550 CalcMin();
ba763a45
RD
551
552 // Applies the layout and repositions/resizes the items
c62ac5b6
RR
553 RecalcSizes();
554}
555
3417c2cd 556void wxSizer::SetSizeHints( wxWindow *window )
5279a24d 557{
34c3ffca
RL
558 // Preserve the window's max size hints, but set the
559 // lower bound according to the sizer calculations.
560
e5251d4f
VZ
561 wxSize size = Fit( window );
562
34c3ffca
RL
563 window->SetSizeHints( size.x,
564 size.y,
565 window->GetMaxWidth(),
566 window->GetMaxHeight() );
5279a24d
RR
567}
568
566d84a7
RL
569void wxSizer::SetVirtualSizeHints( wxWindow *window )
570{
571 // Preserve the window's max size hints, but set the
572 // lower bound according to the sizer calculations.
573
574 FitInside( window );
575 wxSize size( window->GetVirtualSize() );
576 window->SetVirtualSizeHints( size.x,
577 size.y,
578 window->GetMaxWidth(),
579 window->GetMaxHeight() );
580}
581
9cbee2ce 582wxSize wxSizer::GetMaxWindowSize( wxWindow *window ) const
65ba4113 583{
34c3ffca 584 return window->GetMaxSize();
65ba4113
GT
585}
586
3417c2cd 587wxSize wxSizer::GetMinWindowSize( wxWindow *window )
5279a24d 588{
12a3f227
RL
589 wxSize minSize( GetMinSize() );
590 wxSize size( window->GetSize() );
591 wxSize client_size( window->GetClientSize() );
592
77671fd2 593 return wxSize( minSize.x+size.x-client_size.x,
0c0d686f 594 minSize.y+size.y-client_size.y );
5279a24d
RR
595}
596
e11d436b
SC
597// TODO on mac we need a function that determines how much free space this
598// min size contains, in order to make sure that we have 20 pixels of free
599// space around the controls
600
65ba4113
GT
601// Return a window size that will fit within the screens dimensions
602wxSize wxSizer::FitSize( wxWindow *window )
603{
604 wxSize size = GetMinWindowSize( window );
605 wxSize sizeMax = GetMaxWindowSize( window );
606
34c3ffca
RL
607 // Limit the size if sizeMax != wxDefaultSize
608
d775fa82 609 if ( size.x > sizeMax.x && sizeMax.x != wxDefaultCoord )
65ba4113 610 size.x = sizeMax.x;
d775fa82 611 if ( size.y > sizeMax.y && sizeMax.y != wxDefaultCoord )
65ba4113
GT
612 size.y = sizeMax.y;
613
614 return size;
615}
616
9cbee2ce 617wxSize wxSizer::GetMaxClientSize( wxWindow *window ) const
566d84a7
RL
618{
619 wxSize maxSize( window->GetMaxSize() );
620
621 if( maxSize != wxDefaultSize )
622 {
623 wxSize size( window->GetSize() );
624 wxSize client_size( window->GetClientSize() );
625
626 return wxSize( maxSize.x + client_size.x - size.x,
627 maxSize.y + client_size.y - size.y );
628 }
629 else
630 return wxDefaultSize;
631}
632
1b0674f7 633wxSize wxSizer::GetMinClientSize( wxWindow *WXUNUSED(window) )
566d84a7
RL
634{
635 return GetMinSize(); // Already returns client size.
636}
637
638wxSize wxSizer::VirtualFitSize( wxWindow *window )
639{
640 wxSize size = GetMinClientSize( window );
641 wxSize sizeMax = GetMaxClientSize( window );
642
643 // Limit the size if sizeMax != wxDefaultSize
644
d775fa82 645 if ( size.x > sizeMax.x && sizeMax.x != wxDefaultCoord )
566d84a7 646 size.x = sizeMax.x;
d775fa82 647 if ( size.y > sizeMax.y && sizeMax.y != wxDefaultCoord )
566d84a7
RL
648 size.y = sizeMax.y;
649
650 return size;
651}
652
3417c2cd 653void wxSizer::SetDimension( int x, int y, int width, int height )
5279a24d
RR
654{
655 m_position.x = x;
656 m_position.y = y;
657 m_size.x = width;
658 m_size.y = height;
2b5f62a0 659 Layout();
5279a24d
RR
660}
661
f6bcfd97 662wxSize wxSizer::GetMinSize()
3ca6a5f0 663{
f6bcfd97
BP
664 wxSize ret( CalcMin() );
665 if (ret.x < m_minSize.x) ret.x = m_minSize.x;
666 if (ret.y < m_minSize.y) ret.y = m_minSize.y;
3ca6a5f0 667 return ret;
f6bcfd97
BP
668}
669
670void wxSizer::DoSetMinSize( int width, int height )
671{
672 m_minSize.x = width;
673 m_minSize.y = height;
674}
675
676bool wxSizer::DoSetItemMinSize( wxWindow *window, int width, int height )
677{
12a3f227
RL
678 wxASSERT_MSG( window, _T("SetMinSize for NULL window") );
679
680 // Is it our immediate child?
f6bcfd97 681
222ed1d6 682 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
f6bcfd97
BP
683 while (node)
684 {
12a3f227
RL
685 wxSizerItem *item = node->GetData();
686
3ca6a5f0
BP
687 if (item->GetWindow() == window)
688 {
1eba2193 689 item->SetMinSize( width, height );
e0d8fb45 690 return true;
3ca6a5f0 691 }
12a3f227 692 node = node->GetNext();
f6bcfd97
BP
693 }
694
12a3f227
RL
695 // No? Search any subsizers we own then
696
697 node = m_children.GetFirst();
f6bcfd97
BP
698 while (node)
699 {
12a3f227
RL
700 wxSizerItem *item = node->GetData();
701
702 if ( item->GetSizer() &&
703 item->GetSizer()->DoSetItemMinSize( window, width, height ) )
3ca6a5f0 704 {
12a3f227 705 // A child sizer found the requested windw, exit.
e0d8fb45 706 return true;
3ca6a5f0 707 }
12a3f227 708 node = node->GetNext();
f6bcfd97
BP
709 }
710
e0d8fb45 711 return false;
f6bcfd97
BP
712}
713
714bool wxSizer::DoSetItemMinSize( wxSizer *sizer, int width, int height )
715{
12a3f227 716 wxASSERT_MSG( sizer, _T("SetMinSize for NULL sizer") );
f6bcfd97 717
12a3f227
RL
718 // Is it our immediate child?
719
222ed1d6 720 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
f6bcfd97
BP
721 while (node)
722 {
12a3f227
RL
723 wxSizerItem *item = node->GetData();
724
3ca6a5f0
BP
725 if (item->GetSizer() == sizer)
726 {
f6bcfd97 727 item->GetSizer()->DoSetMinSize( width, height );
e0d8fb45 728 return true;
3ca6a5f0 729 }
12a3f227 730 node = node->GetNext();
f6bcfd97
BP
731 }
732
12a3f227
RL
733 // No? Search any subsizers we own then
734
735 node = m_children.GetFirst();
f6bcfd97
BP
736 while (node)
737 {
12a3f227
RL
738 wxSizerItem *item = node->GetData();
739
740 if ( item->GetSizer() &&
741 item->GetSizer()->DoSetItemMinSize( sizer, width, height ) )
3ca6a5f0 742 {
12a3f227 743 // A child found the requested sizer, exit.
e0d8fb45 744 return true;
3ca6a5f0 745 }
12a3f227 746 node = node->GetNext();
f6bcfd97
BP
747 }
748
e0d8fb45 749 return false;
f6bcfd97
BP
750}
751
12a3f227 752bool wxSizer::DoSetItemMinSize( size_t index, int width, int height )
f6bcfd97 753{
222ed1d6 754 wxSizerItemList::compatibility_iterator node = m_children.Item( index );
12a3f227 755
e0d8fb45 756 wxCHECK_MSG( node, false, _T("Failed to find child node") );
12a3f227
RL
757
758 wxSizerItem *item = node->GetData();
f6bcfd97 759
f6bcfd97
BP
760 if (item->GetSizer())
761 {
0ca5105b 762 // Sizers contains the minimal size in them, if not calculated ...
f6bcfd97
BP
763 item->GetSizer()->DoSetMinSize( width, height );
764 }
765 else
766 {
ba763a45 767 // ... but the minimal size of spacers and windows is stored via the item
1eba2193 768 item->SetMinSize( width, height );
f6bcfd97
BP
769 }
770
e0d8fb45 771 return true;
f6bcfd97
BP
772}
773
9f13661f 774wxSizerItem* wxSizer::GetItem( wxWindow *window, bool recursive )
2b5f62a0 775{
9f13661f 776 wxASSERT_MSG( window, _T("GetItem for NULL window") );
12a3f227 777
222ed1d6 778 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
2b5f62a0
VZ
779 while (node)
780 {
12a3f227 781 wxSizerItem *item = node->GetData();
2b5f62a0 782
12a3f227 783 if (item->GetWindow() == window)
2b5f62a0 784 {
9f13661f 785 return item;
2b5f62a0 786 }
8b2bac62
WS
787 else if (recursive && item->IsSizer())
788 {
9f13661f
WS
789 wxSizerItem *subitem = item->GetSizer()->GetItem( window, true );
790 if (subitem)
791 return subitem;
8b2bac62
WS
792 }
793
12a3f227 794 node = node->GetNext();
2b5f62a0 795 }
8b2bac62 796
9f13661f 797 return NULL;
2b5f62a0
VZ
798}
799
9f13661f 800wxSizerItem* wxSizer::GetItem( wxSizer *sizer, bool recursive )
2b5f62a0 801{
9f13661f 802 wxASSERT_MSG( sizer, _T("GetItem for NULL sizer") );
12a3f227 803
222ed1d6 804 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
2b5f62a0
VZ
805 while (node)
806 {
9f13661f 807 wxSizerItem *item = node->GetData();
2b5f62a0 808
12a3f227 809 if (item->GetSizer() == sizer)
2b5f62a0 810 {
9f13661f 811 return item;
2b5f62a0 812 }
8b2bac62
WS
813 else if (recursive && item->IsSizer())
814 {
9f13661f
WS
815 wxSizerItem *subitem = item->GetSizer()->GetItem( sizer, true );
816 if (subitem)
817 return subitem;
8b2bac62
WS
818 }
819
12a3f227 820 node = node->GetNext();
2b5f62a0 821 }
8b2bac62 822
9f13661f
WS
823 return NULL;
824}
825
826wxSizerItem* wxSizer::GetItem( size_t index )
827{
828 wxCHECK_MSG( index < m_children.GetCount(),
829 NULL,
830 _T("GetItem index is out of range") );
831
832 return m_children.Item( index )->GetData();
833}
834
835bool wxSizer::Show( wxWindow *window, bool show, bool recursive )
836{
837 wxSizerItem *item = GetItem( window, recursive );
838
839 if ( item )
840 {
841 item->Show( show );
842 return true;
843 }
844
845 return false;
846}
847
848bool wxSizer::Show( wxSizer *sizer, bool show, bool recursive )
849{
850 wxSizerItem *item = GetItem( sizer, recursive );
851
852 if ( item )
853 {
854 item->Show( show );
855 return true;
856 }
857
8b2bac62 858 return false;
2b5f62a0
VZ
859}
860
8b2bac62 861bool wxSizer::Show( size_t index, bool show)
2b5f62a0 862{
9f13661f 863 wxSizerItem *item = GetItem( index );
2b5f62a0 864
9f13661f
WS
865 if ( item )
866 {
867 item->Show( show );
868 return true;
869 }
8b2bac62 870
9f13661f 871 return false;
12a3f227 872}
2b5f62a0 873
12a3f227
RL
874void wxSizer::ShowItems( bool show )
875{
222ed1d6 876 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
12a3f227
RL
877 while (node)
878 {
879 node->GetData()->Show( show );
880 node = node->GetNext();
2b5f62a0
VZ
881 }
882}
883
9cbee2ce 884bool wxSizer::IsShown( wxWindow *window ) const
2b5f62a0 885{
222ed1d6 886 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
2b5f62a0
VZ
887 while (node)
888 {
12a3f227 889 wxSizerItem *item = node->GetData();
dc259b79 890
12a3f227 891 if (item->GetWindow() == window)
2b5f62a0
VZ
892 {
893 return item->IsShown();
894 }
12a3f227 895 node = node->GetNext();
2b5f62a0
VZ
896 }
897
12a3f227
RL
898 wxFAIL_MSG( _T("IsShown failed to find sizer item") );
899
e0d8fb45 900 return false;
2b5f62a0
VZ
901}
902
9cbee2ce 903bool wxSizer::IsShown( wxSizer *sizer ) const
2b5f62a0 904{
222ed1d6 905 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
2b5f62a0
VZ
906 while (node)
907 {
12a3f227 908 wxSizerItem *item = node->GetData();
2b5f62a0 909
12a3f227 910 if (item->GetSizer() == sizer)
2b5f62a0
VZ
911 {
912 return item->IsShown();
913 }
12a3f227 914 node = node->GetNext();
2b5f62a0
VZ
915 }
916
12a3f227
RL
917 wxFAIL_MSG( _T("IsShown failed to find sizer item") );
918
e0d8fb45 919 return false;
2b5f62a0
VZ
920}
921
9cbee2ce 922bool wxSizer::IsShown( size_t index ) const
12a3f227
RL
923{
924 wxCHECK_MSG( index < m_children.GetCount(),
e0d8fb45 925 false,
12a3f227
RL
926 _T("IsShown index is out of range") );
927
928 return m_children.Item( index )->GetData()->IsShown();
929}
930
931
f6bcfd97
BP
932//---------------------------------------------------------------------------
933// wxGridSizer
934//---------------------------------------------------------------------------
935
936wxGridSizer::wxGridSizer( int rows, int cols, int vgap, int hgap )
12a3f227
RL
937 : m_rows( rows )
938 , m_cols( cols )
939 , m_vgap( vgap )
940 , m_hgap( hgap )
f6bcfd97 941{
02319c24
RD
942 if (m_rows == 0 && m_cols == 0)
943 m_rows = 1;
f6bcfd97
BP
944}
945
946wxGridSizer::wxGridSizer( int cols, int vgap, int hgap )
12a3f227
RL
947 : m_rows( 0 )
948 , m_cols( cols )
949 , m_vgap( vgap )
950 , m_hgap( hgap )
f6bcfd97 951{
02319c24
RD
952 if (m_rows == 0 && m_cols == 0)
953 m_rows = 1;
f6bcfd97
BP
954}
955
0ca5105b 956int wxGridSizer::CalcRowsCols(int& nrows, int& ncols) const
f6bcfd97 957{
f6bcfd97 958 int nitems = m_children.GetCount();
2b5f62a0 959 if ( nitems)
0ca5105b
VZ
960 {
961 if ( m_cols )
962 {
963 ncols = m_cols;
964 nrows = (nitems + m_cols - 1) / m_cols;
965 }
966 else if ( m_rows )
967 {
968 ncols = (nitems + m_rows - 1) / m_rows;
969 nrows = m_rows;
970 }
971 else // 0 columns, 0 rows?
972 {
973 wxFAIL_MSG( _T("grid sizer must have either rows or columns fixed") );
f6bcfd97 974
0ca5105b
VZ
975 nrows = ncols = 0;
976 }
977 }
978
979 return nitems;
980}
981
982void wxGridSizer::RecalcSizes()
983{
984 int nitems, nrows, ncols;
985 if ( (nitems = CalcRowsCols(nrows, ncols)) == 0 )
986 return;
f6bcfd97
BP
987
988 wxSize sz( GetSize() );
989 wxPoint pt( GetPosition() );
3ca6a5f0
BP
990
991 int w = (sz.x - (ncols - 1) * m_hgap) / ncols;
992 int h = (sz.y - (nrows - 1) * m_vgap) / nrows;
f6bcfd97
BP
993
994 int x = pt.x;
995 for (int c = 0; c < ncols; c++)
996 {
997 int y = pt.y;
998 for (int r = 0; r < nrows; r++)
999 {
1000 int i = r * ncols + c;
1001 if (i < nitems)
1002 {
222ed1d6 1003 wxSizerItemList::compatibility_iterator node = m_children.Item( i );
12a3f227
RL
1004
1005 wxASSERT_MSG( node, _T("Failed to find SizerItemList node") );
3ca6a5f0 1006
12a3f227 1007 SetItemBounds( node->GetData(), x, y, w, h);
f6bcfd97
BP
1008 }
1009 y = y + h + m_vgap;
1010 }
1011 x = x + w + m_hgap;
1012 }
1013}
1014
1015wxSize wxGridSizer::CalcMin()
1016{
196be0f1
JS
1017 int nrows, ncols;
1018 if ( CalcRowsCols(nrows, ncols) == 0 )
0ca5105b 1019 return wxSize(10, 10);
f6bcfd97 1020
4f469fb5 1021 // Find the max width and height for any component
f6bcfd97
BP
1022 int w = 0;
1023 int h = 0;
3ca6a5f0 1024
222ed1d6 1025 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
f6bcfd97
BP
1026 while (node)
1027 {
12a3f227
RL
1028 wxSizerItem *item = node->GetData();
1029 wxSize sz( item->CalcMin() );
1030
f6bcfd97
BP
1031 w = wxMax( w, sz.x );
1032 h = wxMax( h, sz.y );
3ca6a5f0 1033
12a3f227 1034 node = node->GetNext();
f6bcfd97 1035 }
3ca6a5f0 1036
12a3f227
RL
1037 return wxSize( ncols * w + (ncols-1) * m_hgap,
1038 nrows * h + (nrows-1) * m_vgap );
f6bcfd97
BP
1039}
1040
1041void wxGridSizer::SetItemBounds( wxSizerItem *item, int x, int y, int w, int h )
1042{
1043 wxPoint pt( x,y );
8b2bac62 1044 wxSize sz( item->GetMinSizeWithBorder() );
f6bcfd97
BP
1045 int flag = item->GetFlag();
1046
1047 if ((flag & wxEXPAND) || (flag & wxSHAPED))
1048 {
1049 sz = wxSize(w, h);
1050 }
1051 else
1052 {
1053 if (flag & wxALIGN_CENTER_HORIZONTAL)
1054 {
559b747d 1055 pt.x = x + (w - sz.x) / 2;
f6bcfd97
BP
1056 }
1057 else if (flag & wxALIGN_RIGHT)
1058 {
559b747d 1059 pt.x = x + (w - sz.x);
f6bcfd97 1060 }
3ca6a5f0 1061
f6bcfd97
BP
1062 if (flag & wxALIGN_CENTER_VERTICAL)
1063 {
559b747d 1064 pt.y = y + (h - sz.y) / 2;
f6bcfd97
BP
1065 }
1066 else if (flag & wxALIGN_BOTTOM)
1067 {
559b747d 1068 pt.y = y + (h - sz.y);
f6bcfd97
BP
1069 }
1070 }
3ca6a5f0 1071
f6bcfd97
BP
1072 item->SetDimension(pt, sz);
1073}
1074
1075//---------------------------------------------------------------------------
1076// wxFlexGridSizer
1077//---------------------------------------------------------------------------
1078
1079wxFlexGridSizer::wxFlexGridSizer( int rows, int cols, int vgap, int hgap )
5d76f462
VZ
1080 : wxGridSizer( rows, cols, vgap, hgap ),
1081 m_flexDirection(wxBOTH),
1082 m_growMode(wxFLEX_GROWMODE_SPECIFIED)
3ca6a5f0 1083{
f6bcfd97
BP
1084}
1085
1086wxFlexGridSizer::wxFlexGridSizer( int cols, int vgap, int hgap )
5d76f462
VZ
1087 : wxGridSizer( cols, vgap, hgap ),
1088 m_flexDirection(wxBOTH),
1089 m_growMode(wxFLEX_GROWMODE_SPECIFIED)
3ca6a5f0 1090{
f6bcfd97 1091}
3ca6a5f0 1092
f6bcfd97
BP
1093wxFlexGridSizer::~wxFlexGridSizer()
1094{
f6bcfd97
BP
1095}
1096
1097void wxFlexGridSizer::RecalcSizes()
1098{
0ca5105b
VZ
1099 int nitems, nrows, ncols;
1100 if ( (nitems = CalcRowsCols(nrows, ncols)) == 0 )
f6bcfd97
BP
1101 return;
1102
20b35a69 1103 wxPoint pt( GetPosition() );
f6bcfd97 1104 wxSize sz( GetSize() );
5d76f462 1105
ba763a45 1106 AdjustForGrowables(sz, m_calculatedMinSize, nrows, ncols);
3ca6a5f0 1107
f6bcfd97
BP
1108 sz = wxSize( pt.x + sz.x, pt.y + sz.y );
1109
1110 int x = pt.x;
1111 for (int c = 0; c < ncols; c++)
1112 {
1113 int y = pt.y;
1114 for (int r = 0; r < nrows; r++)
1115 {
1116 int i = r * ncols + c;
1117 if (i < nitems)
1118 {
222ed1d6 1119 wxSizerItemList::compatibility_iterator node = m_children.Item( i );
12a3f227
RL
1120
1121 wxASSERT_MSG( node, _T("Failed to find node") );
3ca6a5f0 1122
f6bcfd97
BP
1123 int w = wxMax( 0, wxMin( m_colWidths[c], sz.x - x ) );
1124 int h = wxMax( 0, wxMin( m_rowHeights[r], sz.y - y ) );
3ca6a5f0 1125
12a3f227 1126 SetItemBounds( node->GetData(), x, y, w, h);
f6bcfd97
BP
1127 }
1128 y = y + m_rowHeights[r] + m_vgap;
1129 }
1130 x = x + m_colWidths[c] + m_hgap;
1131 }
1132}
1133
1134wxSize wxFlexGridSizer::CalcMin()
1135{
150c8d89
RL
1136 int nrows,
1137 ncols;
1138 size_t i, s;
1139
55f9f0cb 1140 // Number of rows/columns can change as items are added or removed.
5d76f462
VZ
1141 if ( !CalcRowsCols(nrows, ncols) )
1142 return wxSize(10, 10);
f6bcfd97 1143
5d76f462
VZ
1144 m_rowHeights.SetCount(nrows);
1145 m_colWidths.SetCount(ncols);
3ca6a5f0 1146
395a82b1
VZ
1147 // We have to recalcuate the sizes in case the item minimum size has
1148 // changed since the previous layout, or the item has been hidden using
1149 // wxSizer::Show(). If all the items in a row/column are hidden, the final
1150 // dimension of the row/column will be -1, indicating that the column
1151 // itself is hidden.
55f9f0cb
VZ
1152 for( s = m_rowHeights.GetCount(), i = 0; i < s; ++i )
1153 m_rowHeights[ i ] = -1;
1154 for( s = m_colWidths.GetCount(), i = 0; i < s; ++i )
1155 m_colWidths[ i ] = -1;
1156
222ed1d6 1157 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
12a3f227 1158
150c8d89 1159 i = 0;
f6bcfd97
BP
1160 while (node)
1161 {
12a3f227 1162 wxSizerItem *item = node->GetData();
55f9f0cb
VZ
1163 if ( item->IsShown() )
1164 {
1165 wxSize sz( item->CalcMin() );
1166 int row = i / ncols;
1167 int col = i % ncols;
12a3f227 1168
55f9f0cb
VZ
1169 m_rowHeights[ row ] = wxMax( wxMax( 0, sz.y ), m_rowHeights[ row ] );
1170 m_colWidths[ col ] = wxMax( wxMax( 0, sz.x ), m_colWidths[ col ] );
1171 }
3ca6a5f0 1172
12a3f227 1173 node = node->GetNext();
f6bcfd97
BP
1174 i++;
1175 }
3ca6a5f0 1176
20b35a69 1177 AdjustForFlexDirection();
8b2bac62 1178
20b35a69
RD
1179 // Sum total minimum size, including gaps between rows/columns.
1180 // -1 is used as a magic number meaning empty column.
1181 int width = 0;
1182 for (int col = 0; col < ncols; col++)
1183 if ( m_colWidths[ col ] != -1 )
1184 width += m_colWidths[ col ] + ( col == ncols-1 ? 0 : m_hgap );
1185
1186 int height = 0;
1187 for (int row = 0; row < nrows; row++)
1188 if ( m_rowHeights[ row ] != -1 )
1189 height += m_rowHeights[ row ] + ( row == nrows-1 ? 0 : m_vgap );
1190
ba763a45
RD
1191 m_calculatedMinSize = wxSize( width, height );
1192 return m_calculatedMinSize;
20b35a69
RD
1193}
1194
1195void wxFlexGridSizer::AdjustForFlexDirection()
1196{
1197 // the logic in CalcMin works when we resize flexibly in both directions
1198 // but maybe this is not the case
5d76f462
VZ
1199 if ( m_flexDirection != wxBOTH )
1200 {
1201 // select the array corresponding to the direction in which we do *not*
1202 // resize flexibly
1203 wxArrayInt& array = m_flexDirection == wxVERTICAL ? m_colWidths
1204 : m_rowHeights;
1205
1206 const int count = array.GetCount();
1207
1208 // find the largest value in this array
55f9f0cb 1209 int n, largest = 0;
5d76f462
VZ
1210 for ( n = 0; n < count; ++n )
1211 {
1212 if ( array[n] > largest )
1213 largest = array[n];
1214 }
1215
1216 // and now fill it with the largest value
1217 for ( n = 0; n < count; ++n )
1218 {
1219 array[n] = largest;
1220 }
1221 }
8b2bac62 1222}
5d76f462 1223
3ca6a5f0 1224
20b35a69
RD
1225void wxFlexGridSizer::AdjustForGrowables(const wxSize& sz, const wxSize& minsz,
1226 int nrows, int ncols)
1227{
1228 // what to do with the rows? by default, resize them proportionally
1229 if ( sz.y > minsz.y && ( (m_flexDirection & wxVERTICAL) || (m_growMode == wxFLEX_GROWMODE_SPECIFIED) ) )
1230 {
1231 int sum_proportions = 0;
1232 int growable_space = 0;
1233 int num = 0;
1234 size_t idx;
1235 for (idx = 0; idx < m_growableRows.GetCount(); idx++)
1236 {
1237 // Since the number of rows/columns can change as items are
1238 // inserted/deleted, we need to verify at runtime that the
1239 // requested growable rows/columns are still valid.
1240 if (m_growableRows[idx] >= nrows)
1241 continue;
8b2bac62 1242
20b35a69
RD
1243 // If all items in a row/column are hidden, that row/column will
1244 // have a dimension of -1. This causes the row/column to be
1245 // hidden completely.
1246 if (m_rowHeights[ m_growableRows[idx] ] == -1)
1247 continue;
1248 sum_proportions += m_growableRowsProportions[idx];
1249 growable_space += m_rowHeights[ m_growableRows[idx] ];
1250 num++;
1251 }
3ca6a5f0 1252
20b35a69
RD
1253 if (num > 0)
1254 {
1255 for (idx = 0; idx < m_growableRows.GetCount(); idx++)
1256 {
1257 if (m_growableRows[idx] >= nrows )
1258 continue;
1259 if (m_rowHeights[ m_growableRows[idx] ] == -1)
1260 m_rowHeights[ m_growableRows[idx] ] = 0;
1261 else
1262 {
1263 int delta = (sz.y - minsz.y);
1264 if (sum_proportions == 0)
1265 delta = (delta/num) + m_rowHeights[ m_growableRows[idx] ];
1266 else
1267 delta = ((delta+growable_space)*m_growableRowsProportions[idx]) / sum_proportions;
1268 m_rowHeights[ m_growableRows[idx] ] = delta;
1269 }
1270 }
1271 }
1272 }
1273 else if ( (m_growMode == wxFLEX_GROWMODE_ALL) && (sz.y > minsz.y) )
1274 {
1275 // rounding problem?
1276 for ( int row = 0; row < nrows; ++row )
1277 m_rowHeights[ row ] = sz.y / nrows;
1278 }
1279
1280 // the same logic as above but for the columns
1281 if ( sz.x > minsz.x && ( (m_flexDirection & wxHORIZONTAL) || (m_growMode == wxFLEX_GROWMODE_SPECIFIED) ) )
1282 {
1283 int sum_proportions = 0;
1284 int growable_space = 0;
1285 int num = 0;
1286 size_t idx;
1287 for (idx = 0; idx < m_growableCols.GetCount(); idx++)
1288 {
1289 // Since the number of rows/columns can change as items are
1290 // inserted/deleted, we need to verify at runtime that the
1291 // requested growable rows/columns are still valid.
1292 if (m_growableCols[idx] >= ncols)
1293 continue;
8b2bac62 1294
20b35a69
RD
1295 // If all items in a row/column are hidden, that row/column will
1296 // have a dimension of -1. This causes the column to be hidden
1297 // completely.
1298 if (m_colWidths[ m_growableCols[idx] ] == -1)
1299 continue;
1300 sum_proportions += m_growableColsProportions[idx];
1301 growable_space += m_colWidths[ m_growableCols[idx] ];
1302 num++;
1303 }
1304
1305 if (num > 0)
1306 {
1307 for (idx = 0; idx < m_growableCols.GetCount(); idx++)
1308 {
1309 if (m_growableCols[idx] >= ncols )
1310 continue;
1311 if (m_colWidths[ m_growableCols[idx] ] == -1)
1312 m_colWidths[ m_growableCols[idx] ] = 0;
1313 else
1314 {
1315 int delta = (sz.x - minsz.x);
1316 if (sum_proportions == 0)
1317 delta = (delta/num) + m_colWidths[ m_growableCols[idx] ];
1318 else
1319 delta = ((delta+growable_space)*m_growableColsProportions[idx])/sum_proportions;
1320 m_colWidths[ m_growableCols[idx] ] = delta;
1321 }
1322 }
1323 }
1324 }
1325 else if ( (m_growMode == wxFLEX_GROWMODE_ALL) && (sz.x > minsz.x) )
1326 {
1327 for ( int col=0; col < ncols; ++col )
1328 m_colWidths[ col ] = sz.x / ncols;
1329 }
f6bcfd97
BP
1330}
1331
20b35a69 1332
e8800dcf 1333void wxFlexGridSizer::AddGrowableRow( size_t idx, int proportion )
f6bcfd97
BP
1334{
1335 m_growableRows.Add( idx );
e8800dcf 1336 m_growableRowsProportions.Add( proportion );
f6bcfd97
BP
1337}
1338
8d2474f4 1339void wxFlexGridSizer::RemoveGrowableRow( size_t idx )
f6bcfd97 1340{
8d2474f4 1341 m_growableRows.Remove( idx );
f6bcfd97
BP
1342}
1343
e8800dcf 1344void wxFlexGridSizer::AddGrowableCol( size_t idx, int proportion )
f6bcfd97
BP
1345{
1346 m_growableCols.Add( idx );
e8800dcf 1347 m_growableColsProportions.Add( proportion );
f6bcfd97
BP
1348}
1349
8d2474f4 1350void wxFlexGridSizer::RemoveGrowableCol( size_t idx )
f6bcfd97 1351{
8d2474f4 1352 m_growableCols.Remove( idx );
f6bcfd97
BP
1353}
1354
c62ac5b6 1355//---------------------------------------------------------------------------
92afa2b1 1356// wxBoxSizer
61d514bb
RR
1357//---------------------------------------------------------------------------
1358
92afa2b1 1359wxBoxSizer::wxBoxSizer( int orient )
12a3f227 1360 : m_orient( orient )
61d514bb 1361{
61d514bb
RR
1362}
1363
92afa2b1 1364void wxBoxSizer::RecalcSizes()
61d514bb
RR
1365{
1366 if (m_children.GetCount() == 0)
61d514bb 1367 return;
0c0d686f 1368
61d514bb 1369 int delta = 0;
61d514bb
RR
1370 if (m_stretchable)
1371 {
1372 if (m_orient == wxHORIZONTAL)
85e5cfc9 1373 delta = m_size.x - m_fixedWidth;
3ca6a5f0 1374 else
85e5cfc9 1375 delta = m_size.y - m_fixedHeight;
61d514bb 1376 }
0c0d686f 1377
61d514bb 1378 wxPoint pt( m_position );
0c0d686f 1379
222ed1d6 1380 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
61d514bb
RR
1381 while (node)
1382 {
12a3f227
RL
1383 wxSizerItem *item = node->GetData();
1384
2b5f62a0 1385 if (item->IsShown())
3ca6a5f0 1386 {
ba763a45 1387 wxSize size( item->GetMinSizeWithBorder() );
3ca6a5f0 1388
2b5f62a0 1389 if (m_orient == wxVERTICAL)
3ca6a5f0 1390 {
2b5f62a0 1391 wxCoord height = size.y;
12a3f227 1392 if (item->GetProportion())
2b5f62a0 1393 {
85e5cfc9
VZ
1394 // Because of at least one visible item has non-zero
1395 // proportion then m_stretchable is not zero
1396 height = (delta * item->GetProportion()) / m_stretchable;
2b5f62a0
VZ
1397 }
1398
1399 wxPoint child_pos( pt );
42841dfc 1400 wxSize child_size( size.x, height );
2b5f62a0
VZ
1401
1402 if (item->GetFlag() & (wxEXPAND | wxSHAPED))
1403 child_size.x = m_size.x;
1404 else if (item->GetFlag() & wxALIGN_RIGHT)
1405 child_pos.x += m_size.x - size.x;
1406 else if (item->GetFlag() & (wxCENTER | wxALIGN_CENTER_HORIZONTAL))
1407 // XXX wxCENTER is added for backward compatibility;
1408 // wxALIGN_CENTER should be used in new code
1409 child_pos.x += (m_size.x - size.x) / 2;
1410
1411 item->SetDimension( child_pos, child_size );
1412
1413 pt.y += height;
1414 }
1415 else
1416 {
1417 wxCoord width = size.x;
12a3f227 1418 if (item->GetProportion())
2b5f62a0 1419 {
85e5cfc9
VZ
1420 // Because of at least one visible item has non-zero
1421 // proportion then m_stretchable is not zero
1422 width = (delta * item->GetProportion()) / m_stretchable;
2b5f62a0
VZ
1423 }
1424
1425 wxPoint child_pos( pt );
42841dfc 1426 wxSize child_size( width, size.y );
2b5f62a0
VZ
1427
1428 if (item->GetFlag() & (wxEXPAND | wxSHAPED))
1429 child_size.y = m_size.y;
1430 else if (item->GetFlag() & wxALIGN_BOTTOM)
1431 child_pos.y += m_size.y - size.y;
1432 else if (item->GetFlag() & (wxCENTER | wxALIGN_CENTER_VERTICAL))
1433 // XXX wxCENTER is added for backward compatibility;
1434 // wxALIGN_CENTER should be used in new code
1435 child_pos.y += (m_size.y - size.y) / 2;
1436
1437 item->SetDimension( child_pos, child_size );
1438
1439 pt.x += width;
3ca6a5f0 1440 }
3ca6a5f0
BP
1441 }
1442
12a3f227 1443 node = node->GetNext();
61d514bb
RR
1444 }
1445}
1446
92afa2b1 1447wxSize wxBoxSizer::CalcMin()
61d514bb
RR
1448{
1449 if (m_children.GetCount() == 0)
c7a9fa36 1450 return wxSize(10,10);
0c0d686f 1451
61d514bb
RR
1452 m_stretchable = 0;
1453 m_minWidth = 0;
1454 m_minHeight = 0;
1455 m_fixedWidth = 0;
1456 m_fixedHeight = 0;
0c0d686f 1457
ba763a45 1458 // precalc item minsizes and count proportions
222ed1d6 1459 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
85e5cfc9
VZ
1460 while (node)
1461 {
1462 wxSizerItem *item = node->GetData();
12a3f227 1463
ba763a45
RD
1464 if (item->IsShown())
1465 item->CalcMin(); // result is stored in the item
8b2bac62 1466
85e5cfc9
VZ
1467 if (item->IsShown() && item->GetProportion() != 0)
1468 m_stretchable += item->GetProportion();
1469
1470 node = node->GetNext();
1471 }
1472
1473 // Total minimum size (width or height) of sizer
1474 int maxMinSize = 0;
1475
1476 node = m_children.GetFirst();
61d514bb 1477 while (node)
f98de448 1478 {
85e5cfc9 1479 wxSizerItem *item = node->GetData();
12a3f227
RL
1480
1481 if (item->IsShown() && item->GetProportion() != 0)
f98de448 1482 {
12a3f227 1483 int stretch = item->GetProportion();
ba763a45 1484 wxSize size( item->GetMinSizeWithBorder() );
85e5cfc9 1485 int minSize;
8b2bac62 1486
f98de448 1487 // Integer division rounded up is (a + b - 1) / b
85e5cfc9
VZ
1488 // Round up needed in order to guarantee that all
1489 // all items will have size not less then their min size
f98de448 1490 if (m_orient == wxHORIZONTAL)
85e5cfc9 1491 minSize = ( size.x*m_stretchable + stretch - 1)/stretch;
f98de448 1492 else
85e5cfc9 1493 minSize = ( size.y*m_stretchable + stretch - 1)/stretch;
8b2bac62 1494
85e5cfc9
VZ
1495 if (minSize > maxMinSize)
1496 maxMinSize = minSize;
f98de448 1497 }
12a3f227 1498 node = node->GetNext();
f98de448 1499 }
12a3f227 1500
4f469fb5
RR
1501 // Calculate overall minimum size
1502 node = m_children.GetFirst();
f98de448 1503 while (node)
61d514bb 1504 {
85e5cfc9 1505 wxSizerItem *item = node->GetData();
12a3f227 1506
2b5f62a0 1507 if (item->IsShown())
f98de448 1508 {
ba763a45 1509 wxSize size( item->GetMinSizeWithBorder() );
12a3f227 1510 if (item->GetProportion() != 0)
2b5f62a0
VZ
1511 {
1512 if (m_orient == wxHORIZONTAL)
85e5cfc9 1513 size.x = (maxMinSize*item->GetProportion())/m_stretchable;
2b5f62a0 1514 else
85e5cfc9 1515 size.y = (maxMinSize*item->GetProportion())/m_stretchable;
3ca6a5f0
BP
1516 }
1517 else
2b5f62a0
VZ
1518 {
1519 if (m_orient == wxVERTICAL)
1520 {
1521 m_fixedHeight += size.y;
1522 m_fixedWidth = wxMax( m_fixedWidth, size.x );
1523 }
1524 else
1525 {
1526 m_fixedWidth += size.x;
1527 m_fixedHeight = wxMax( m_fixedHeight, size.y );
1528 }
1529 }
85e5cfc9
VZ
1530
1531 if (m_orient == wxHORIZONTAL)
1532 {
1533 m_minWidth += size.x;
1534 m_minHeight = wxMax( m_minHeight, size.y );
1535 }
1536 else
1537 {
1538 m_minHeight += size.y;
1539 m_minWidth = wxMax( m_minWidth, size.x );
1540 }
2b5f62a0 1541 }
12a3f227 1542 node = node->GetNext();
61d514bb 1543 }
0c0d686f 1544
61d514bb
RR
1545 return wxSize( m_minWidth, m_minHeight );
1546}
27ea1d8a
RR
1547
1548//---------------------------------------------------------------------------
1549// wxStaticBoxSizer
1550//---------------------------------------------------------------------------
1551
1e6feb95
VZ
1552#if wxUSE_STATBOX
1553
27ea1d8a 1554wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox *box, int orient )
12a3f227
RL
1555 : wxBoxSizer( orient )
1556 , m_staticBox( box )
27ea1d8a 1557{
223d09f6 1558 wxASSERT_MSG( box, wxT("wxStaticBoxSizer needs a static box") );
27ea1d8a 1559}
0c0d686f 1560
12a3f227
RL
1561static void GetStaticBoxBorders( wxStaticBox *box,
1562 int *borderTop,
1563 int *borderOther)
84028727
VZ
1564{
1565 // this has to be done platform by platform as there is no way to
1566 // guess the thickness of a wxStaticBox border
ec4e4a14
DE
1567#ifdef __WXCOCOA__
1568 box->GetBordersForSizer(borderTop,borderOther);
67021102
DS
1569#elif defined(__WXMAC__)
1570
1571 static int extraTop = -1; // Uninitted
1572 static int other = 5;
1573
1574 if ( extraTop == -1 )
1575 {
67021102
DS
1576 // The minimal border used for the top. Later on the staticbox'
1577 // font height is added to this.
1578 extraTop = 0;
1579
78ca5669 1580 if ( UMAGetSystemVersion() >= 0x1030 /*Panther*/ )
67021102
DS
1581 {
1582 // As indicated by the HIG, Panther needs an extra border of 11
1583 // pixels (otherwise overlapping occurs at the top). The "other"
1584 // border has to be 11.
1585 extraTop = 11;
8b2bac62 1586 other = 11;
67021102
DS
1587 }
1588
1589 }
1590
1591 *borderTop = extraTop + box->GetCharHeight();
1592 *borderOther = other;
1593
1594#else
84028727 1595#ifdef __WXGTK__
56eee37f 1596 if ( box->GetLabel().empty() )
84028727
VZ
1597 *borderTop = 5;
1598 else
1599#endif // __WXGTK__
f2b99f63
JS
1600 *borderTop = box->GetCharHeight();
1601
84028727 1602 *borderOther = 5;
ec4e4a14 1603#endif // __WXCOCOA__
84028727
VZ
1604}
1605
27ea1d8a
RR
1606void wxStaticBoxSizer::RecalcSizes()
1607{
84028727
VZ
1608 int top_border, other_border;
1609 GetStaticBoxBorders(m_staticBox, &top_border, &other_border);
27ea1d8a
RR
1610
1611 m_staticBox->SetSize( m_position.x, m_position.y, m_size.x, m_size.y );
0c0d686f 1612
27ea1d8a
RR
1613 wxPoint old_pos( m_position );
1614 m_position.x += other_border;
1615 m_position.y += top_border;
1616 wxSize old_size( m_size );
1617 m_size.x -= 2*other_border;
1618 m_size.y -= top_border + other_border;
0c0d686f 1619
27ea1d8a 1620 wxBoxSizer::RecalcSizes();
0c0d686f 1621
27ea1d8a
RR
1622 m_position = old_pos;
1623 m_size = old_size;
1624}
1625
1626wxSize wxStaticBoxSizer::CalcMin()
1627{
84028727
VZ
1628 int top_border, other_border;
1629 GetStaticBoxBorders(m_staticBox, &top_border, &other_border);
0c0d686f 1630
27ea1d8a 1631 wxSize ret( wxBoxSizer::CalcMin() );
cae31b8b 1632 ret.x += 2*other_border;
27ea1d8a 1633 ret.y += other_border + top_border;
0c0d686f 1634
27ea1d8a
RR
1635 return ret;
1636}
83edc0a5 1637
eb2a7883
VZ
1638void wxStaticBoxSizer::ShowItems( bool show )
1639{
1640 m_staticBox->Show( show );
1641 wxBoxSizer::ShowItems( show );
1642}
1643
1e6feb95
VZ
1644#endif // wxUSE_STATBOX
1645
974c2a59
WS
1646#if wxUSE_BUTTON
1647
acf2ac37
RR
1648wxStdDialogButtonSizer::wxStdDialogButtonSizer()
1649 : wxBoxSizer(wxHORIZONTAL)
1650{
1651 bool is_pda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA);
1652
974c2a59 1653 // If we have a PDA screen, put yes/no button over
acf2ac37
RR
1654 // all other buttons, otherwise on the left side.
1655 if (is_pda)
1656 m_orient = wxVERTICAL;
974c2a59 1657
acf2ac37
RR
1658 m_buttonAffirmative = NULL;
1659 m_buttonApply = NULL;
1660 m_buttonNegative = NULL;
1661 m_buttonCancel = NULL;
1662 m_buttonHelp = NULL;
1663}
1664
1665void wxStdDialogButtonSizer::AddButton(wxButton *mybutton)
1666{
1667 switch (mybutton->GetId())
1668 {
1669 case wxID_OK:
1670 case wxID_YES:
1671 case wxID_SAVE:
1672 m_buttonAffirmative = mybutton;
1673 break;
1674 case wxID_APPLY:
1675 m_buttonApply = mybutton;
1676 break;
1677 case wxID_NO:
1678 m_buttonNegative = mybutton;
1679 break;
1680 case wxID_CANCEL:
1681 m_buttonCancel = mybutton;
1682 break;
1683 case wxID_HELP:
1684 m_buttonHelp = mybutton;
1685 break;
1686 default:
1687 break;
1688 }
1689}
1690
b181a505
RR
1691void wxStdDialogButtonSizer::SetAffirmativeButton( wxButton *button )
1692{
1693 m_buttonAffirmative = button;
1694}
1695
1696void wxStdDialogButtonSizer::SetNegativeButton( wxButton *button )
1697{
1698 m_buttonNegative = button;
1699}
1700
1701void wxStdDialogButtonSizer::SetCancelButton( wxButton *button )
1702{
1703 m_buttonCancel = button;
1704}
1705
acf2ac37
RR
1706void wxStdDialogButtonSizer::Finalise()
1707{
1708#ifdef __WXMAC__
1709 Add(0, 0, 0, wxLEFT, 6);
1710 if (m_buttonHelp)
974c2a59
WS
1711 Add((wxWindow*)m_buttonHelp, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 6);
1712
acf2ac37
RR
1713 if (m_buttonNegative){
1714 // HIG POLICE BULLETIN - destructive buttons need extra padding
1715 // 24 pixels on either side
1716 Add((wxWindow*)m_buttonNegative, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 12);
1717 }
974c2a59 1718
acf2ac37 1719 // extra whitespace between help/negative and cancel/ok buttons
974c2a59
WS
1720 Add(0, 0, 1, wxEXPAND, 0);
1721
acf2ac37
RR
1722 if (m_buttonCancel){
1723 Add((wxWindow*)m_buttonCancel, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 6);
1724 // Cancel or help should be default
1725 // m_buttonCancel->SetDefaultButton();
1726 }
974c2a59
WS
1727
1728 // Ugh, Mac doesn't really have apply dialogs, so I'll just
acf2ac37
RR
1729 // figure the best place is between Cancel and OK
1730 if (m_buttonApply)
1731 Add((wxWindow*)m_buttonApply, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 6);
974c2a59 1732
acf2ac37
RR
1733 if (m_buttonAffirmative){
1734 Add((wxWindow*)m_buttonAffirmative, 0, wxALIGN_CENTRE | wxLEFT, 6);
974c2a59 1735
acf2ac37
RR
1736 if (m_buttonAffirmative->GetId() == wxID_SAVE){
1737 // these buttons have set labels under Mac so we should use them
1738 m_buttonAffirmative->SetLabel(_("Save"));
1739 m_buttonNegative->SetLabel(_("Don't Save"));
1740 }
1741 }
974c2a59 1742
acf2ac37
RR
1743 // Extra space around and at the right
1744 Add(12, 24);
1745#elif defined(__WXGTK20__)
1746 Add(0, 0, 0, wxLEFT, 9);
1747 if (m_buttonHelp)
974c2a59
WS
1748 Add((wxWindow*)m_buttonHelp, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 3);
1749
acf2ac37 1750 // extra whitespace between help and cancel/ok buttons
974c2a59
WS
1751 Add(0, 0, 1, wxEXPAND, 0);
1752
acf2ac37
RR
1753 if (m_buttonNegative){
1754 Add((wxWindow*)m_buttonNegative, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 3);
1755 }
974c2a59 1756
acf2ac37
RR
1757 if (m_buttonCancel){
1758 Add((wxWindow*)m_buttonCancel, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 3);
1759 // Cancel or help should be default
1760 // m_buttonCancel->SetDefaultButton();
1761 }
974c2a59 1762
acf2ac37
RR
1763 if (m_buttonApply)
1764 Add((wxWindow*)m_buttonApply, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 3);
974c2a59 1765
acf2ac37
RR
1766 if (m_buttonAffirmative)
1767 Add((wxWindow*)m_buttonAffirmative, 0, wxALIGN_CENTRE | wxLEFT, 6);
1768#else
1769 // do the same thing for GTK1 and Windows platforms
1770 // and assume any platform not accounted for here will use
1771 // Windows style
1772 Add(0, 0, 0, wxLEFT, 9);
1773 if (m_buttonHelp)
974c2a59
WS
1774 Add((wxWindow*)m_buttonHelp, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, m_buttonHelp->ConvertDialogToPixels(wxSize(4, 0)).x);
1775
acf2ac37 1776 // extra whitespace between help and cancel/ok buttons
974c2a59 1777 Add(0, 0, 1, wxEXPAND, 0);
acf2ac37
RR
1778
1779 if (m_buttonApply)
1780 Add((wxWindow*)m_buttonApply, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, m_buttonApply->ConvertDialogToPixels(wxSize(4, 0)).x);
974c2a59 1781
acf2ac37
RR
1782 if (m_buttonAffirmative){
1783 Add((wxWindow*)m_buttonAffirmative, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, m_buttonAffirmative->ConvertDialogToPixels(wxSize(4, 0)).x);
1784 }
974c2a59 1785
acf2ac37
RR
1786 if (m_buttonNegative){
1787 Add((wxWindow*)m_buttonNegative, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, m_buttonNegative->ConvertDialogToPixels(wxSize(4, 0)).x);
1788 }
974c2a59 1789
acf2ac37
RR
1790 if (m_buttonCancel){
1791 Add((wxWindow*)m_buttonCancel, 0, wxALIGN_CENTRE | wxLEFT, m_buttonCancel->ConvertDialogToPixels(wxSize(4, 0)).x);
1792 // Cancel or help should be default
1793 // m_buttonCancel->SetDefaultButton();
1794 }
974c2a59 1795
acf2ac37
RR
1796#endif
1797}
adbf2d73 1798
974c2a59
WS
1799#endif // wxUSE_BUTTON
1800
adbf2d73
VS
1801#if WXWIN_COMPATIBILITY_2_4
1802
ade4eb65 1803// ----------------------------------------------------------------------------
83edc0a5 1804// wxNotebookSizer
ade4eb65 1805// ----------------------------------------------------------------------------
83edc0a5 1806
adbf2d73
VS
1807#if wxUSE_BOOKCTRL
1808IMPLEMENT_CLASS(wxBookCtrlSizer, wxSizer)
1809#if wxUSE_NOTEBOOK
1810IMPLEMENT_CLASS(wxNotebookSizer, wxBookCtrlSizer)
1811#endif // wxUSE_NOTEBOOK
1812#endif // wxUSE_BOOKCTRL
1813
ade4eb65 1814#if wxUSE_BOOKCTRL
60be2f47 1815
61c083e7 1816wxBookCtrlSizer::wxBookCtrlSizer(wxBookCtrlBase *bookctrl)
ade4eb65 1817 : m_bookctrl(bookctrl)
83edc0a5 1818{
ade4eb65 1819 wxASSERT_MSG( bookctrl, wxT("wxBookCtrlSizer needs a control") );
83edc0a5
RR
1820}
1821
ade4eb65 1822void wxBookCtrlSizer::RecalcSizes()
83edc0a5 1823{
ade4eb65 1824 m_bookctrl->SetSize( m_position.x, m_position.y, m_size.x, m_size.y );
83edc0a5
RR
1825}
1826
ade4eb65 1827wxSize wxBookCtrlSizer::CalcMin()
83edc0a5 1828{
ade4eb65 1829 wxSize sizeBorder = m_bookctrl->CalcSizeFromPage(wxSize(0, 0));
1e6feb95
VZ
1830
1831 sizeBorder.x += 5;
1832 sizeBorder.y += 5;
3ca6a5f0 1833
ade4eb65 1834 if ( m_bookctrl->GetPageCount() == 0 )
1e6feb95
VZ
1835 {
1836 return wxSize(sizeBorder.x + 10, sizeBorder.y + 10);
1837 }
83edc0a5
RR
1838
1839 int maxX = 0;
1840 int maxY = 0;
1841
ade4eb65
VZ
1842 wxWindowList::compatibility_iterator
1843 node = m_bookctrl->GetChildren().GetFirst();
83edc0a5
RR
1844 while (node)
1845 {
1846 wxWindow *item = node->GetData();
3ca6a5f0
BP
1847 wxSizer *itemsizer = item->GetSizer();
1848
1849 if (itemsizer)
1850 {
83edc0a5 1851 wxSize subsize( itemsizer->CalcMin() );
83edc0a5 1852
1e6feb95
VZ
1853 if (subsize.x > maxX)
1854 maxX = subsize.x;
1855 if (subsize.y > maxY)
1856 maxY = subsize.y;
3ca6a5f0
BP
1857 }
1858
1859 node = node->GetNext();
83edc0a5
RR
1860 }
1861
1e6feb95 1862 return wxSize( maxX, maxY ) + sizeBorder;
83edc0a5
RR
1863}
1864
2d480e40
RD
1865#if wxUSE_NOTEBOOK
1866
1867wxNotebookSizer::wxNotebookSizer(wxNotebook *nb)
2d480e40 1868{
adbf2d73
VS
1869 wxASSERT_MSG( nb, wxT("wxNotebookSizer needs a control") );
1870 m_bookctrl = nb;
2d480e40
RD
1871}
1872
1873#endif // wxUSE_NOTEBOOOK
ade4eb65 1874#endif // wxUSE_BOOKCTRL
34c3ffca 1875
adbf2d73 1876#endif // WXWIN_COMPATIBILITY_2_4