]>
git.saurik.com Git - wxWidgets.git/blob - src/common/sizer.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: provide new wxSizer class for layounting
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 //---------------------------------------------------------------------------
31 wxSizerItem::wxSizerItem( int width
, int height
, int option
, int flag
, int border
)
33 m_window
= (wxWindow
*) NULL
;
34 m_sizer
= (wxSizer
*) NULL
;
39 // minimal size is the initial size
43 // size is set directly
47 wxSizerItem::wxSizerItem( wxWindow
*window
, int option
, int flag
, int border
)
50 m_sizer
= (wxSizer
*) NULL
;
55 // minimal size is the initial size
56 m_minSize
= window
->GetSize();
58 // size is calculated later
62 wxSizerItem::wxSizerItem( wxSizer
*sizer
, int option
, int flag
, int border
)
64 m_window
= (wxWindow
*) NULL
;
70 // minimal size is calculated later
73 // size is calculated later
77 wxSize
wxSizerItem::GetSize()
81 ret
= m_sizer
->GetSize();
84 ret
= m_window
->GetSize();
99 wxSize
wxSizerItem::CalcMin()
103 ret
= m_sizer
->CalcMin();
105 The minimum size of a window should be the
106 initial size, as saved in m_minSize, not the
111 ret = m_window->GetSize();
113 else ret
= m_minSize
;
119 if (m_flag
& wxNORTH
)
121 if (m_flag
& wxSOUTH
)
127 void wxSizerItem::SetDimension( wxPoint pos
, wxSize size
)
138 if (m_flag
& wxNORTH
)
143 if (m_flag
& wxSOUTH
)
149 m_sizer
->SetDimension( pos
.x
, pos
.y
, size
.x
, size
.y
);
152 m_window
->SetSize( pos
.x
, pos
.y
, size
.x
, size
.y
);
157 bool wxSizerItem::IsWindow()
159 return (m_window
!= NULL
);
162 bool wxSizerItem::IsSizer()
164 return (m_sizer
!= NULL
);
167 bool wxSizerItem::IsSpacer()
169 return (m_window
== NULL
) && (m_sizer
== NULL
);
172 //---------------------------------------------------------------------------
174 //---------------------------------------------------------------------------
178 m_children
.DeleteContents( TRUE
);
185 void wxSizer::Add( wxWindow
*window
, int option
, int flag
, int border
)
187 m_children
.Append( new wxSizerItem( window
, option
, flag
, border
) );
190 void wxSizer::Add( wxSizer
*sizer
, int option
, int flag
, int border
)
192 m_children
.Append( new wxSizerItem( sizer
, option
, flag
, border
) );
195 void wxSizer::Add( int width
, int height
, int option
, int flag
, int border
)
197 m_children
.Append( new wxSizerItem( width
, height
, option
, flag
, border
) );
200 void wxSizer::Prepend( wxWindow
*window
, int option
, int flag
, int border
)
202 m_children
.Insert( new wxSizerItem( window
, option
, flag
, border
) );
205 void wxSizer::Prepend( wxSizer
*sizer
, int option
, int flag
, int border
)
207 m_children
.Insert( new wxSizerItem( sizer
, option
, flag
, border
) );
210 void wxSizer::Prepend( int width
, int height
, int option
, int flag
, int border
)
212 m_children
.Insert( new wxSizerItem( width
, height
, option
, flag
, border
) );
215 bool wxSizer::Remove( wxWindow
*window
)
219 wxNode
*node
= m_children
.First();
222 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
223 if (item
->GetWindow() == window
)
225 m_children
.DeleteNode( node
);
234 bool wxSizer::Remove( wxSizer
*sizer
)
238 wxNode
*node
= m_children
.First();
241 wxSizerItem
*item
= (wxSizerItem
*)node
->Data();
242 if (item
->GetSizer() == sizer
)
244 m_children
.DeleteNode( node
);
253 bool wxSizer::Remove( int pos
)
255 wxNode
*node
= m_children
.Nth( pos
);
256 if (!node
) return FALSE
;
258 m_children
.DeleteNode( node
);
263 void wxSizer::Fit( wxWindow
*window
)
265 window
->SetSize( GetMinWindowSize( window
) );
268 void wxSizer::Layout()
274 void wxSizer::SetSizeHints( wxWindow
*window
)
276 wxSize
size( GetMinWindowSize( window
) );
277 window
->SetSizeHints( size
.x
, size
.y
);
280 wxSize
wxSizer::GetMinWindowSize( wxWindow
*window
)
282 wxSize
minSize( GetMinSize() );
283 wxSize
size( window
->GetSize() );
284 wxSize
client_size( window
->GetClientSize() );
285 return wxSize( minSize
.x
+size
.x
-client_size
.x
,
286 minSize
.y
+size
.y
-client_size
.y
);
289 void wxSizer::SetDimension( int x
, int y
, int width
, int height
)
299 //---------------------------------------------------------------------------
301 //---------------------------------------------------------------------------
303 wxBoxSizer::wxBoxSizer( int orient
)
308 void wxBoxSizer::RecalcSizes()
310 if (m_children
.GetCount() == 0)
317 if (m_orient
== wxHORIZONTAL
)
319 delta
= (m_size
.x
- m_fixedWidth
) / m_stretchable
;
320 extra
= (m_size
.x
- m_fixedWidth
) % m_stretchable
;
324 delta
= (m_size
.y
- m_fixedHeight
) / m_stretchable
;
325 extra
= (m_size
.y
- m_fixedHeight
) % m_stretchable
;
329 wxPoint
pt( m_position
);
331 wxNode
*node
= m_children
.GetFirst();
334 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
337 if (item
->GetOption())
338 weight
= item
->GetOption();
340 wxSize
size( item
->CalcMin() );
342 if (m_orient
== wxVERTICAL
)
344 long height
= size
.y
;
345 if (item
->GetOption())
347 height
= (delta
* weight
) + extra
;
348 extra
= 0; // only the first item will get the remainder as extra size
351 wxPoint
child_pos( pt
);
352 wxSize
child_size( wxSize( size
.x
, height
) );
354 if (item
->GetFlag() & wxALIGN_RIGHT
)
355 child_pos
.x
+= m_size
.x
- size
.x
;
356 else if (item
->GetFlag() & wxCENTER
)
357 child_pos
.x
+= (m_size
.x
- size
.x
) / 2;
358 else if (item
->GetFlag() & wxEXPAND
)
359 child_size
.x
= m_size
.x
;
361 item
->SetDimension( child_pos
, child_size
);
368 if (item
->GetOption())
370 width
= (delta
* weight
) + extra
;
371 extra
= 0; // only the first item will get the remainder as extra size
374 wxPoint
child_pos( pt
);
375 wxSize
child_size( wxSize(width
, size
.y
) );
377 if (item
->GetFlag() & wxALIGN_BOTTOM
)
378 child_pos
.y
+= m_size
.y
- size
.y
;
379 else if (item
->GetFlag() & wxCENTER
)
380 child_pos
.y
+= (m_size
.y
- size
.y
) / 2;
381 else if (item
->GetFlag() & wxEXPAND
)
382 child_size
.y
= m_size
.y
;
384 item
->SetDimension( child_pos
, child_size
);
393 wxSize
wxBoxSizer::CalcMin()
395 if (m_children
.GetCount() == 0)
404 wxNode
*node
= m_children
.GetFirst();
407 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
410 if (item
->GetOption())
411 weight
= item
->GetOption();
413 wxSize
size( item
->CalcMin() );
415 if (m_orient
== wxHORIZONTAL
)
417 m_minWidth
+= (size
.x
* weight
);
418 m_minHeight
= wxMax( m_minHeight
, size
.y
);
422 m_minHeight
+= (size
.y
* weight
);
423 m_minWidth
= wxMax( m_minWidth
, size
.x
);
426 if (item
->GetOption())
428 m_stretchable
+= weight
;
432 if (m_orient
== wxVERTICAL
)
434 m_fixedHeight
+= size
.y
;
435 m_fixedWidth
= wxMax( m_fixedWidth
, size
.x
);
439 m_fixedWidth
+= size
.x
;
440 m_fixedHeight
= wxMax( m_fixedHeight
, size
.y
);
447 return wxSize( m_minWidth
, m_minHeight
);
450 //---------------------------------------------------------------------------
452 //---------------------------------------------------------------------------
454 wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox
*box
, int orient
)
455 : wxBoxSizer( orient
)
457 wxASSERT_MSG( box
, _T("wxStaticBoxSizer needs a static box") );
462 void wxStaticBoxSizer::RecalcSizes()
464 // this will have to be done platform by platform
465 // as there is no way to guess the thickness of
466 // a wxStaticBox border
468 if (m_staticBox
->GetLabel().IsEmpty()) top_border
= 5;
469 int other_border
= 5;
471 m_staticBox
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y
);
473 wxPoint
old_pos( m_position
);
474 m_position
.x
+= other_border
;
475 m_position
.y
+= top_border
;
476 wxSize
old_size( m_size
);
477 m_size
.x
-= 2*other_border
;
478 m_size
.y
-= top_border
+ other_border
;
480 wxBoxSizer::RecalcSizes();
482 m_position
= old_pos
;
486 wxSize
wxStaticBoxSizer::CalcMin()
488 // this will have to be done platform by platform
489 // as there is no way to guess the thickness of
490 // a wxStaticBox border
492 if (m_staticBox
->GetLabel().IsEmpty()) top_border
= 5;
493 int other_border
= 5;
495 wxSize
ret( wxBoxSizer::CalcMin() );
496 ret
.x
+= 2*top_border
;
497 ret
.y
+= other_border
+ top_border
;