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