]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/sizer.cpp
Added support for locales like de_AT.iso-8859-1
[wxWidgets.git] / src / common / sizer.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: sizer.cpp
3// Purpose: provide new wxSizer class for layounting
4// Author: Robert Roebling and Robin Dunn
5// Modified by:
6// Created:
7// RCS-ID: $Id$
8// Copyright: (c) Robin Dunn, Dirk Holtwick and Robert Roebling
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "sizer.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20 #pragma hdrstop
21#endif
22
23#include "wx/sizer.h"
24#include "wx/utils.h"
25#include "wx/statbox.h"
26
27//---------------------------------------------------------------------------
28// wxSizerItem
29//---------------------------------------------------------------------------
30
31wxSizerItem::wxSizerItem( int width, int height, int option, int flag, int border )
32{
33 m_window = (wxWindow *) NULL;
34 m_sizer = (wxSizer *) NULL;
35 m_option = option;
36 m_border = border;
37 m_flag = flag;
38
39 // minimal size is the initial size
40 m_minSize.x = width;
41 m_minSize.y = height;
42
43 // size is set directly
44 m_size = m_minSize;
45}
46
47wxSizerItem::wxSizerItem( wxWindow *window, int option, int flag, int border )
48{
49 m_window = window;
50 m_sizer = (wxSizer *) NULL;
51 m_option = option;
52 m_border = border;
53 m_flag = flag;
54
55 // minimal size is the initial size
56 m_minSize = window->GetSize();
57
58 // size is calculated later
59 // m_size = ...
60}
61
62wxSizerItem::wxSizerItem( wxSizer *sizer, int option, int flag, int border )
63{
64 m_window = (wxWindow *) NULL;
65 m_sizer = sizer;
66 m_option = option;
67 m_border = border;
68 m_flag = flag;
69
70 // minimal size is calculated later
71 // m_minSize = ...
72
73 // size is calculated later
74 // m_size = ...
75}
76
77wxSize wxSizerItem::GetSize()
78{
79 wxSize ret;
80 if (IsSizer())
81 ret = m_sizer->GetSize();
82 else
83 if (IsWindow())
84 ret = m_window->GetSize();
85 else ret = m_size;
86
87 if (m_flag & wxWEST)
88 ret.x += m_border;
89 if (m_flag & wxEAST)
90 ret.x += m_border;
91 if (m_flag & wxNORTH)
92 ret.y += m_border;
93 if (m_flag & wxSOUTH)
94 ret.y += m_border;
95
96 return ret;
97}
98
99wxSize wxSizerItem::CalcMin()
100{
101 wxSize ret;
102 if (IsSizer())
103 ret = m_sizer->CalcMin();
104/*
105 The minimum size of a window should be the
106 initial size, as saved in m_minSize, not the
107 current size.
108
109 else
110 if (IsWindow())
111 ret = m_window->GetSize();
112*/
113 else ret = m_minSize;
114
115 if (m_flag & wxWEST)
116 ret.x += m_border;
117 if (m_flag & wxEAST)
118 ret.x += m_border;
119 if (m_flag & wxNORTH)
120 ret.y += m_border;
121 if (m_flag & wxSOUTH)
122 ret.y += m_border;
123
124 return ret;
125}
126
127void wxSizerItem::SetDimension( wxPoint pos, wxSize size )
128{
129 if (m_flag & wxWEST)
130 {
131 pos.x += m_border;
132 size.x -= m_border;
133 }
134 if (m_flag & wxEAST)
135 {
136 size.x -= m_border;
137 }
138 if (m_flag & wxNORTH)
139 {
140 pos.y += m_border;
141 size.y -= m_border;
142 }
143 if (m_flag & wxSOUTH)
144 {
145 size.y -= m_border;
146 }
147
148 if (IsSizer())
149 m_sizer->SetDimension( pos.x, pos.y, size.x, size.y );
150
151 if (IsWindow())
152 m_window->SetSize( pos.x, pos.y, size.x, size.y );
153
154 m_size = size;
155}
156
157bool wxSizerItem::IsWindow()
158{
159 return (m_window != NULL);
160}
161
162bool wxSizerItem::IsSizer()
163{
164 return (m_sizer != NULL);
165}
166
167bool wxSizerItem::IsSpacer()
168{
169 return (m_window == NULL) && (m_sizer == NULL);
170}
171
172//---------------------------------------------------------------------------
173// wxSizer
174//---------------------------------------------------------------------------
175
176wxSizer::wxSizer()
177{
178 m_children.DeleteContents( TRUE );
179}
180
181wxSizer::~wxSizer()
182{
183}
184
185void wxSizer::Add( wxWindow *window, int option, int flag, int border )
186{
187 m_children.Append( new wxSizerItem( window, option, flag, border ) );
188}
189
190void wxSizer::Add( wxSizer *sizer, int option, int flag, int border )
191{
192 m_children.Append( new wxSizerItem( sizer, option, flag, border ) );
193}
194
195void wxSizer::Add( int width, int height, int option, int flag, int border )
196{
197 m_children.Append( new wxSizerItem( width, height, option, flag, border ) );
198}
199
200void wxSizer::Prepend( wxWindow *window, int option, int flag, int border )
201{
202 m_children.Insert( new wxSizerItem( window, option, flag, border ) );
203}
204
205void wxSizer::Prepend( wxSizer *sizer, int option, int flag, int border )
206{
207 m_children.Insert( new wxSizerItem( sizer, option, flag, border ) );
208}
209
210void wxSizer::Prepend( int width, int height, int option, int flag, int border )
211{
212 m_children.Insert( new wxSizerItem( width, height, option, flag, border ) );
213}
214
215bool wxSizer::Remove( wxWindow *window )
216{
217 wxASSERT( window );
218
219 wxNode *node = m_children.First();
220 while (node)
221 {
222 wxSizerItem *item = (wxSizerItem*)node->Data();
223 if (item->GetWindow() == window)
224 {
225 m_children.DeleteNode( node );
226 return TRUE;
227 }
228 node = node->Next();
229 }
230
231 return FALSE;
232}
233
234bool wxSizer::Remove( wxSizer *sizer )
235{
236 wxASSERT( sizer );
237
238 wxNode *node = m_children.First();
239 while (node)
240 {
241 wxSizerItem *item = (wxSizerItem*)node->Data();
242 if (item->GetSizer() == sizer)
243 {
244 m_children.DeleteNode( node );
245 return TRUE;
246 }
247 node = node->Next();
248 }
249
250 return FALSE;
251}
252
253bool wxSizer::Remove( int pos )
254{
255 wxNode *node = m_children.Nth( pos );
256 if (!node) return FALSE;
257
258 m_children.DeleteNode( node );
259
260 return TRUE;
261}
262
263void wxSizer::Fit( wxWindow *window )
264{
265 window->SetSize( GetMinWindowSize( window ) );
266}
267
268void wxSizer::Layout()
269{
270 CalcMin();
271 RecalcSizes();
272}
273
274void wxSizer::SetSizeHints( wxWindow *window )
275{
276 wxSize size( GetMinWindowSize( window ) );
277 window->SetSizeHints( size.x, size.y );
278}
279
280wxSize wxSizer::GetMinWindowSize( wxWindow *window )
281{
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 );
287}
288
289void wxSizer::SetDimension( int x, int y, int width, int height )
290{
291 m_position.x = x;
292 m_position.y = y;
293 m_size.x = width;
294 m_size.y = height;
295 CalcMin();
296 RecalcSizes();
297}
298
299//---------------------------------------------------------------------------
300// wxBoxSizer
301//---------------------------------------------------------------------------
302
303wxBoxSizer::wxBoxSizer( int orient )
304{
305 m_orient = orient;
306}
307
308void wxBoxSizer::RecalcSizes()
309{
310 if (m_children.GetCount() == 0)
311 return;
312
313 int delta = 0;
314 int extra = 0;
315 if (m_stretchable)
316 {
317 if (m_orient == wxHORIZONTAL)
318 {
319 delta = (m_size.x - m_fixedWidth) / m_stretchable;
320 extra = (m_size.x - m_fixedWidth) % m_stretchable;
321 }
322 else
323 {
324 delta = (m_size.y - m_fixedHeight) / m_stretchable;
325 extra = (m_size.y - m_fixedHeight) % m_stretchable;
326 }
327 }
328
329 wxPoint pt( m_position );
330
331 wxNode *node = m_children.GetFirst();
332 while (node)
333 {
334 wxSizerItem *item = (wxSizerItem*) node->Data();
335
336 int weight = 1;
337 if (item->GetOption())
338 weight = item->GetOption();
339
340 wxSize size( item->CalcMin() );
341
342 if (m_orient == wxVERTICAL)
343 {
344 long height = size.y;
345 if (item->GetOption())
346 {
347 height = (delta * weight) + extra;
348 extra = 0; // only the first item will get the remainder as extra size
349 }
350
351 wxPoint child_pos( pt );
352 wxSize child_size( wxSize( size.x, height) );
353
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;
360
361 item->SetDimension( child_pos, child_size );
362
363 pt.y += height;
364 }
365 else
366 {
367 long width = size.x;
368 if (item->GetOption())
369 {
370 width = (delta * weight) + extra;
371 extra = 0; // only the first item will get the remainder as extra size
372 }
373
374 wxPoint child_pos( pt );
375 wxSize child_size( wxSize(width, size.y) );
376
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;
383
384 item->SetDimension( child_pos, child_size );
385
386 pt.x += width;
387 }
388
389 node = node->Next();
390 }
391}
392
393wxSize wxBoxSizer::CalcMin()
394{
395 if (m_children.GetCount() == 0)
396 return wxSize(2,2);
397
398 m_stretchable = 0;
399 m_minWidth = 0;
400 m_minHeight = 0;
401 m_fixedWidth = 0;
402 m_fixedHeight = 0;
403
404 wxNode *node = m_children.GetFirst();
405 while (node)
406 {
407 wxSizerItem *item = (wxSizerItem*) node->Data();
408
409 int weight = 1;
410 if (item->GetOption())
411 weight = item->GetOption();
412
413 wxSize size( item->CalcMin() );
414
415 if (m_orient == wxHORIZONTAL)
416 {
417 m_minWidth += (size.x * weight);
418 m_minHeight = wxMax( m_minHeight, size.y );
419 }
420 else
421 {
422 m_minHeight += (size.y * weight);
423 m_minWidth = wxMax( m_minWidth, size.x );
424 }
425
426 if (item->GetOption())
427 {
428 m_stretchable += weight;
429 }
430 else
431 {
432 if (m_orient == wxVERTICAL)
433 {
434 m_fixedHeight += size.y;
435 m_fixedWidth = wxMax( m_fixedWidth, size.x );
436 }
437 else
438 {
439 m_fixedWidth += size.x;
440 m_fixedHeight = wxMax( m_fixedHeight, size.y );
441 }
442 }
443
444 node = node->Next();
445 }
446
447 return wxSize( m_minWidth, m_minHeight );
448}
449
450//---------------------------------------------------------------------------
451// wxStaticBoxSizer
452//---------------------------------------------------------------------------
453
454wxStaticBoxSizer::wxStaticBoxSizer( wxStaticBox *box, int orient )
455 : wxBoxSizer( orient )
456{
457 wxASSERT_MSG( box, _T("wxStaticBoxSizer needs a static box") );
458
459 m_staticBox = box;
460}
461
462void wxStaticBoxSizer::RecalcSizes()
463{
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
467 int top_border = 15;
468 if (m_staticBox->GetLabel().IsEmpty()) top_border = 5;
469 int other_border = 5;
470
471 m_staticBox->SetSize( m_position.x, m_position.y, m_size.x, m_size.y );
472
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;
479
480 wxBoxSizer::RecalcSizes();
481
482 m_position = old_pos;
483 m_size = old_size;
484}
485
486wxSize wxStaticBoxSizer::CalcMin()
487{
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
491 int top_border = 15;
492 if (m_staticBox->GetLabel().IsEmpty()) top_border = 5;
493 int other_border = 5;
494
495 wxSize ret( wxBoxSizer::CalcMin() );
496 ret.x += 2*top_border;
497 ret.y += other_border + top_border;
498
499 return ret;
500}