]>
git.saurik.com Git - wxWidgets.git/blob - src/common/sizer.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: provide new wxSizer class for layout
4 // Author: Robert Roebling and Robin Dunn
8 // Copyright: (c) Robin Dunn, Dirk Holtwick and Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "sizer.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
25 #include "wx/statbox.h"
27 //---------------------------------------------------------------------------
29 IMPLEMENT_ABSTRACT_CLASS(wxSizerItem
, wxObject
);
30 IMPLEMENT_ABSTRACT_CLASS(wxSizer
, wxObject
);
31 IMPLEMENT_ABSTRACT_CLASS(wxBoxSizer
, wxSizer
);
32 IMPLEMENT_ABSTRACT_CLASS(wxStaticBoxSizer
, wxBoxSizer
);
34 //---------------------------------------------------------------------------
36 //---------------------------------------------------------------------------
38 wxSizerItem::wxSizerItem( int width
, int height
, int option
, int flag
, int border
, wxObject
* userData
)
40 m_window
= (wxWindow
*) NULL
;
41 m_sizer
= (wxSizer
*) NULL
;
45 m_userData
= userData
;
47 // minimal size is the initial size
51 // size is set directly
55 wxSizerItem::wxSizerItem( wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
58 m_sizer
= (wxSizer
*) NULL
;
62 m_userData
= userData
;
64 // minimal size is the initial size
65 m_minSize
= window
->GetSize();
67 // size is calculated later
71 wxSizerItem::wxSizerItem( wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
73 m_window
= (wxWindow
*) NULL
;
78 m_userData
= userData
;
80 // minimal size is calculated later
83 // size is calculated later
87 wxSizerItem::~wxSizerItem()
96 wxSize
wxSizerItem::GetSize()
100 ret
= m_sizer
->GetSize();
103 ret
= m_window
->GetSize();
110 if (m_flag
& wxNORTH
)
112 if (m_flag
& wxSOUTH
)
118 wxSize
wxSizerItem::CalcMin()
122 ret
= m_sizer
->CalcMin();
124 The minimum size of a window should be the
125 initial size, as saved in m_minSize, not the
130 ret = m_window->GetSize();
132 else ret
= m_minSize
;
138 if (m_flag
& wxNORTH
)
140 if (m_flag
& wxSOUTH
)
146 void wxSizerItem::SetDimension( wxPoint pos
, wxSize size
)
157 if (m_flag
& wxNORTH
)
162 if (m_flag
& wxSOUTH
)
168 m_sizer
->SetDimension( pos
.x
, pos
.y
, size
.x
, size
.y
);
171 m_window
->SetSize( pos
.x
, pos
.y
, size
.x
, size
.y
);
176 bool wxSizerItem::IsWindow()
178 return (m_window
!= NULL
);
181 bool wxSizerItem::IsSizer()
183 return (m_sizer
!= NULL
);
186 bool wxSizerItem::IsSpacer()
188 return (m_window
== NULL
) && (m_sizer
== NULL
);
191 //---------------------------------------------------------------------------
193 //---------------------------------------------------------------------------
197 m_children
.DeleteContents( TRUE
);
204 void wxSizer::Add( wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
206 m_children
.Append( new wxSizerItem( window
, option
, flag
, border
, userData
) );
209 void wxSizer::Add( wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
211 m_children
.Append( new wxSizerItem( sizer
, option
, flag
, border
, userData
) );
214 void wxSizer::Add( int width
, int height
, int option
, int flag
, int border
, wxObject
* userData
)
216 m_children
.Append( new wxSizerItem( width
, height
, option
, flag
, border
, userData
) );
219 void wxSizer::Prepend( wxWindow
*window
, int option
, int flag
, int border
, wxObject
* userData
)
221 m_children
.Insert( new wxSizerItem( window
, option
, flag
, border
, userData
) );
224 void wxSizer::Prepend( wxSizer
*sizer
, int option
, int flag
, int border
, wxObject
* userData
)
226 m_children
.Insert( new wxSizerItem( sizer
, option
, flag
, border
, userData
) );
229 void wxSizer::Prepend( int width
, int height
, int option
, int flag
, int border
, wxObject
* userData
)
231 m_children
.Insert( new wxSizerItem( width
, height
, option
, flag
, border
, userData
) );
234 bool wxSizer::Remove( wxWindow
*window
)
238 wxNode
*node
= m_children
.First();
241 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
242 if (item
->GetWindow() == window
)
244 m_children
.DeleteNode( node
);
253 bool wxSizer::Remove( wxSizer
*sizer
)
257 wxNode
*node
= m_children
.First();
260 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
261 if (item
->GetSizer() == sizer
)
263 m_children
.DeleteNode( node
);
272 bool wxSizer::Remove( int pos
)
274 wxNode
*node
= m_children
.Nth( pos
);
275 if (!node
) return FALSE
;
277 m_children
.DeleteNode( node
);
282 void wxSizer::Fit( wxWindow
*window
)
284 window
->SetSize( GetMinWindowSize( window
) );
287 void wxSizer::Layout()
293 void wxSizer::SetSizeHints( wxWindow
*window
)
295 wxSize
size( GetMinWindowSize( window
) );
296 window
->SetSizeHints( size
.x
, size
.y
);
299 wxSize
wxSizer::GetMinWindowSize( wxWindow
*window
)
301 wxSize
minSize( GetMinSize() );
302 wxSize
size( window
->GetSize() );
303 wxSize
client_size( window
->GetClientSize() );
304 return wxSize( minSize
.x
+size
.x
-client_size
.x
,
305 minSize
.y
+size
.y
-client_size
.y
);
308 void wxSizer::SetDimension( int x
, int y
, int width
, int height
)
318 //---------------------------------------------------------------------------
320 //---------------------------------------------------------------------------
322 wxBoxSizer::wxBoxSizer( int orient
)
327 void wxBoxSizer::RecalcSizes()
329 if (m_children
.GetCount() == 0)
336 if (m_orient
== wxHORIZONTAL
)
338 delta
= (m_size
.x
- m_fixedWidth
) / m_stretchable
;
339 extra
= (m_size
.x
- m_fixedWidth
) % m_stretchable
;
343 delta
= (m_size
.y
- m_fixedHeight
) / m_stretchable
;
344 extra
= (m_size
.y
- m_fixedHeight
) % m_stretchable
;
348 wxPoint
pt( m_position
);
350 wxNode
*node
= m_children
.GetFirst();
353 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
356 if (item
->GetOption())
357 weight
= item
->GetOption();
359 wxSize
size( item
->CalcMin() );
361 if (m_orient
== wxVERTICAL
)
363 long height
= size
.y
;
364 if (item
->GetOption())
366 height
= (delta
* weight
) + extra
;
367 extra
= 0; // only the first item will get the remainder as extra size
370 wxPoint
child_pos( pt
);
371 wxSize
child_size( wxSize( size
.x
, height
) );
373 if (item
->GetFlag() & wxALIGN_RIGHT
)
374 child_pos
.x
+= m_size
.x
- size
.x
;
375 else if (item
->GetFlag() & wxCENTER
)
376 child_pos
.x
+= (m_size
.x
- size
.x
) / 2;
377 else if (item
->GetFlag() & wxEXPAND
)
378 child_size
.x
= m_size
.x
;
380 item
->SetDimension( child_pos
, child_size
);
387 if (item
->GetOption())
389 width
= (delta
* weight
) + extra
;
390 extra
= 0; // only the first item will get the remainder as extra size
393 wxPoint
child_pos( pt
);
394 wxSize
child_size( wxSize(width
, size
.y
) );
396 if (item
->GetFlag() & wxALIGN_BOTTOM
)
397 child_pos
.y
+= m_size
.y
- size
.y
;
398 else if (item
->GetFlag() & wxCENTER
)
399 child_pos
.y
+= (m_size
.y
- size
.y
) / 2;
400 else if (item
->GetFlag() & wxEXPAND
)
401 child_size
.y
= m_size
.y
;
403 item
->SetDimension( child_pos
, child_size
);
412 wxSize
wxBoxSizer::CalcMin()
414 if (m_children
.GetCount() == 0)
423 wxNode
*node
= m_children
.GetFirst();
426 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
429 if (item
->GetOption())
430 weight
= item
->GetOption();
432 wxSize
size( item
->CalcMin() );
434 if (m_orient
== wxHORIZONTAL
)
436 m_minWidth
+= (size
.x
* weight
);
437 m_minHeight
= wxMax( m_minHeight
, size
.y
);
441 m_minHeight
+= (size
.y
* weight
);
442 m_minWidth
= wxMax( m_minWidth
, size
.x
);
445 if (item
->GetOption())
447 m_stretchable
+= weight
;
451 if (m_orient
== wxVERTICAL
)
453 m_fixedHeight
+= size
.y
;
454 m_fixedWidth
= wxMax( m_fixedWidth
, size
.x
);
458 m_fixedWidth
+= size
.x
;
459 m_fixedHeight
= wxMax( m_fixedHeight
, size
.y
);
466 return wxSize( m_minWidth
, m_minHeight
);
469 //---------------------------------------------------------------------------
471 //---------------------------------------------------------------------------
473 wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox
*box
, int orient
)
474 : wxBoxSizer( orient
)
476 wxASSERT_MSG( box
, wxT("wxStaticBoxSizer needs a static box") );
481 void wxStaticBoxSizer::RecalcSizes()
483 // this will have to be done platform by platform
484 // as there is no way to guess the thickness of
485 // a wxStaticBox border
487 if (m_staticBox
->GetLabel().IsEmpty()) top_border
= 5;
488 int other_border
= 5;
490 m_staticBox
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y
);
492 wxPoint
old_pos( m_position
);
493 m_position
.x
+= other_border
;
494 m_position
.y
+= top_border
;
495 wxSize
old_size( m_size
);
496 m_size
.x
-= 2*other_border
;
497 m_size
.y
-= top_border
+ other_border
;
499 wxBoxSizer::RecalcSizes();
501 m_position
= old_pos
;
505 wxSize
wxStaticBoxSizer::CalcMin()
507 // this will have to be done platform by platform
508 // as there is no way to guess the thickness of
509 // a wxStaticBox border
511 if (m_staticBox
->GetLabel().IsEmpty()) top_border
= 5;
512 int other_border
= 5;
514 wxSize
ret( wxBoxSizer::CalcMin() );
515 ret
.x
+= 2*top_border
;
516 ret
.y
+= other_border
+ top_border
;