5dbc84608be943bc2dd32c5a75bde358e8802d0d
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::Fit( wxWindow
*window
)
202 window
->SetSize( GetMinWindowSize( window
) );
205 void wxSizer::Layout()
211 void wxSizer::SetSizeHints( wxWindow
*window
)
213 wxSize
size( GetMinWindowSize( window
) );
214 window
->SetSizeHints( size
.x
, size
.y
);
217 wxSize
wxSizer::GetMinWindowSize( wxWindow
*window
)
219 wxSize
minSize( GetMinSize() );
220 wxSize
size( window
->GetSize() );
221 wxSize
client_size( window
->GetClientSize() );
222 return wxSize( minSize
.x
+size
.x
-client_size
.x
,
223 minSize
.y
+size
.y
-client_size
.y
);
226 void wxSizer::SetDimension( int x
, int y
, int width
, int height
)
235 //---------------------------------------------------------------------------
237 //---------------------------------------------------------------------------
239 wxBoxSizer::wxBoxSizer( int orient
)
244 void wxBoxSizer::RecalcSizes()
246 if (m_children
.GetCount() == 0)
248 SetDimension( m_position
.x
, m_position
.y
, 2, 2 );
256 if (m_orient
== wxHORIZONTAL
)
258 delta
= (m_size
.x
- m_fixedWidth
) / m_stretchable
;
259 extra
= (m_size
.x
- m_fixedWidth
) % m_stretchable
;
263 delta
= (m_size
.y
- m_fixedHeight
) / m_stretchable
;
264 extra
= (m_size
.y
- m_fixedHeight
) % m_stretchable
;
268 wxPoint
pt( m_position
);
270 wxNode
*node
= m_children
.GetFirst();
273 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
276 if (item
->GetOption())
277 weight
= item
->GetOption();
279 wxSize
size( item
->CalcMin() );
281 if (m_orient
== wxVERTICAL
)
283 long height
= size
.y
;
284 if (item
->GetOption())
286 height
= (delta
* weight
) + extra
;
287 extra
= 0; // only the first item will get the remainder as extra size
290 wxPoint
child_pos( pt
);
291 wxSize
child_size( wxSize( size
.x
, height
) );
293 if (item
->GetFlag() & wxALIGN_RIGHT
)
294 child_pos
.x
+= m_size
.x
- size
.x
;
295 else if (item
->GetFlag() & wxCENTER
)
296 child_pos
.x
+= (m_size
.x
- size
.x
) / 2;
297 else if (item
->GetFlag() & wxEXPAND
)
298 child_size
.x
= m_size
.x
;
300 item
->SetDimension( child_pos
, child_size
);
307 if (item
->GetOption())
309 width
= (delta
* weight
) + extra
;
310 extra
= 0; // only the first item will get the remainder as extra size
313 wxPoint
child_pos( pt
);
314 wxSize
child_size( wxSize(width
, size
.y
) );
316 if (item
->GetFlag() & wxALIGN_BOTTOM
)
317 child_pos
.y
+= m_size
.y
- size
.y
;
318 else if (item
->GetFlag() & wxCENTER
)
319 child_pos
.y
+= (m_size
.y
- size
.y
) / 2;
320 else if (item
->GetFlag() & wxEXPAND
)
321 child_size
.y
= m_size
.y
;
323 item
->SetDimension( child_pos
, child_size
);
332 wxSize
wxBoxSizer::CalcMin()
334 if (m_children
.GetCount() == 0)
343 wxNode
*node
= m_children
.GetFirst();
346 wxSizerItem
*item
= (wxSizerItem
*) node
->Data();
349 if (item
->GetOption())
350 weight
= item
->GetOption();
352 wxSize
size( item
->CalcMin() );
354 if (m_orient
== wxHORIZONTAL
)
356 m_minWidth
+= (size
.x
* weight
);
357 m_minHeight
= wxMax( m_minHeight
, size
.y
);
361 m_minHeight
+= (size
.y
* weight
);
362 m_minWidth
= wxMax( m_minWidth
, size
.x
);
365 if (item
->GetOption())
367 m_stretchable
+= weight
;
371 if (m_orient
== wxVERTICAL
)
373 m_fixedHeight
+= size
.y
;
374 m_fixedWidth
= wxMax( m_fixedWidth
, size
.x
);
378 m_fixedWidth
+= size
.x
;
379 m_fixedHeight
= wxMax( m_fixedHeight
, size
.y
);
386 return wxSize( m_minWidth
, m_minHeight
);
389 //---------------------------------------------------------------------------
391 //---------------------------------------------------------------------------
393 wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox
*box
, int orient
)
394 : wxBoxSizer( orient
)
396 wxASSERT_MSG( box
, _T("wxStaticBoxSizer needs a static box") );
401 void wxStaticBoxSizer::RecalcSizes()
403 // this will have to be done platform by platform
404 // as there is no way to guess the thickness of
405 // a wxStaticBox border
407 if (m_staticBox
->GetLabel().IsEmpty()) top_border
= 5;
408 int other_border
= 5;
410 m_staticBox
->SetSize( m_position
.x
, m_position
.y
, m_size
.x
, m_size
.y
);
412 wxPoint
old_pos( m_position
);
413 m_position
.x
+= other_border
;
414 m_position
.y
+= top_border
;
415 wxSize
old_size( m_size
);
416 m_size
.x
-= 2*other_border
;
417 m_size
.y
-= top_border
+ other_border
;
419 wxBoxSizer::RecalcSizes();
421 m_position
= old_pos
;
425 wxSize
wxStaticBoxSizer::CalcMin()
427 // this will have to be done platform by platform
428 // as there is no way to guess the thickness of
429 // a wxStaticBox border
431 if (m_staticBox
->GetLabel().IsEmpty()) top_border
= 5;
432 int other_border
= 5;
434 wxSize
ret( wxBoxSizer::CalcMin() );
435 ret
.x
+= 2*top_border
;
436 ret
.y
+= other_border
+ top_border
;