1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: provide wxSizer class for layout
4 // Author: Robert Roebling and Robin Dunn
5 // Modified by: Ron Lee, Vadim Zeitlin (wxSizerFlags)
8 // Copyright: (c) Robin Dunn, Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
15 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
16 #pragma interface "sizer.h"
21 #include "wx/window.h"
23 #include "wx/dialog.h"
24 #include "wx/bookctrl.h"
26 //---------------------------------------------------------------------------
28 //---------------------------------------------------------------------------
30 class WXDLLEXPORT wxSizerItem
;
31 class WXDLLEXPORT wxSizer
;
32 class WXDLLEXPORT wxBoxSizer
;
35 // ----------------------------------------------------------------------------
36 // wxSizerFlags: flags used for an item in the sizer
37 // ----------------------------------------------------------------------------
39 class WXDLLEXPORT wxSizerFlags
42 // construct the flags object initialized with the given proportion (0 by
44 wxSizerFlags(int proportion
= 0) : m_proportion(proportion
)
50 // setters for all sizer flags, they all return the object itself so that
51 // calls to them can be chained
53 wxSizerFlags
& Proportion(int proportion
)
55 m_proportion
= proportion
;
59 wxSizerFlags
& Align(int alignment
) // combination of wxAlignment values
67 // some shortcuts for Align()
68 wxSizerFlags
& Expand() { return Align(wxEXPAND
); }
69 wxSizerFlags
& Centre() { return Align(wxCENTRE
); }
70 wxSizerFlags
& Center() { return Centre(); }
73 wxSizerFlags
& Border(int direction
, int borderInPixels
)
78 m_borderInPixels
= borderInPixels
;
83 wxSizerFlags
& Border(int direction
= wxALL
)
85 // FIXME: default border size shouldn't be hardcoded
86 return Border(direction
, 5);
90 // accessors for wxSizer only
91 int GetProportion() const { return m_proportion
; }
92 int GetFlags() const { return m_flags
; }
93 int GetBorderInPixels() const { return m_borderInPixels
; }
102 //---------------------------------------------------------------------------
104 //---------------------------------------------------------------------------
106 class WXDLLEXPORT wxSizerItem
: public wxObject
110 wxSizerItem(wxWindow
*window
, const wxSizerFlags
& flags
)
118 wxSizerItem(wxSizer
*sizer
, const wxSizerFlags
& flags
)
126 wxSizerItem( wxWindow
*window
,
130 wxObject
* userData
);
133 wxSizerItem( wxSizer
*sizer
,
137 wxObject
* userData
);
140 wxSizerItem( int width
,
148 virtual ~wxSizerItem();
150 virtual void DeleteWindows();
152 // Enable deleting the SizerItem without destroying the contained sizer.
156 virtual wxSize
GetSize() const;
157 virtual wxSize
CalcMin();
158 virtual void SetDimension( wxPoint pos
, wxSize size
);
160 wxSize
GetMinSize() const
161 { return m_minSize
; }
162 wxSize
GetMinSizeWithBorder() const;
164 void SetMinSize(const wxSize
& size
)
166 if (IsWindow()) m_window
->SetMinSize(size
);
169 void SetMinSize( int x
, int y
)
170 { SetMinSize(wxSize(x
, y
)); }
171 void SetInitSize( int x
, int y
)
172 { SetMinSize(wxSize(x
, y
)); }
174 void SetRatio( int width
, int height
)
175 // if either of dimensions is zero, ratio is assumed to be 1
176 // to avoid "divide by zero" errors
177 { m_ratio
= (width
&& height
) ? ((float) width
/ (float) height
) : 1; }
178 void SetRatio( wxSize size
)
179 { m_ratio
= (size
.x
&& size
.y
) ? ((float) size
.x
/ (float) size
.y
) : 1; }
180 void SetRatio( float ratio
)
182 float GetRatio() const
185 virtual wxRect
GetRect() { return m_zoneRect
; }
187 bool IsWindow() const;
188 bool IsSizer() const;
189 bool IsSpacer() const;
191 // Deprecated in 2.6, use {G,S}etProportion instead.
192 wxDEPRECATED( void SetOption( int option
) );
193 wxDEPRECATED( int GetOption() const );
195 void SetProportion( int proportion
)
196 { m_proportion
= proportion
; }
197 int GetProportion() const
198 { return m_proportion
; }
199 void SetFlag( int flag
)
203 void SetBorder( int border
)
204 { m_border
= border
; }
205 int GetBorder() const
208 wxWindow
*GetWindow() const
210 void SetWindow( wxWindow
*window
)
211 { m_window
= window
; m_minSize
= window
->GetSize(); }
212 wxSizer
*GetSizer() const
214 void SetSizer( wxSizer
*sizer
)
216 const wxSize
&GetSpacer() const
218 void SetSpacer( const wxSize
&size
)
219 { m_size
= size
; m_minSize
= size
; }
221 void Show ( bool show
);
225 wxObject
* GetUserData() const
226 { return m_userData
; }
227 wxPoint
GetPosition() const
231 // common part of several ctors
234 // common part of ctors taking wxSizerFlags
235 void Init(const wxSizerFlags
& flags
);
246 wxRect m_zoneRect
; // Rectangle for window or item (not including borders)
248 // If true, then this item is considered in the layout
249 // calculation. Otherwise, it is skipped over.
252 // Aspect ratio can always be calculated from m_size,
253 // but this would cause precision loss when the window
254 // is shrunk. It is safer to preserve the initial value.
257 wxObject
*m_userData
;
260 DECLARE_CLASS(wxSizerItem
)
261 DECLARE_NO_COPY_CLASS(wxSizerItem
)
264 WX_DECLARE_EXPORTED_LIST( wxSizerItem
, wxSizerItemList
);
267 //---------------------------------------------------------------------------
269 //---------------------------------------------------------------------------
271 class WXDLLEXPORT wxSizer
: public wxObject
, public wxClientDataContainer
277 // methods for adding elements to the sizer: there are Add/Insert/Prepend
278 // overloads for each of window/sizer/spacer/wxSizerItem
279 inline wxSizerItem
* Add( wxWindow
*window
,
283 wxObject
* userData
= NULL
);
284 inline wxSizerItem
* Add( wxSizer
*sizer
,
288 wxObject
* userData
= NULL
);
289 inline wxSizerItem
* Add( int width
,
294 wxObject
* userData
= NULL
);
295 inline wxSizerItem
* Add( wxWindow
*window
, const wxSizerFlags
& flags
);
296 inline wxSizerItem
* Add( wxSizer
*sizer
, const wxSizerFlags
& flags
);
297 inline wxSizerItem
* Add( wxSizerItem
*item
);
299 inline wxSizerItem
* AddSpacer(int size
);
300 inline wxSizerItem
* AddStretchSpacer(int prop
= 1);
302 inline wxSizerItem
* Insert( size_t index
,
307 wxObject
* userData
= NULL
);
308 inline wxSizerItem
* Insert( size_t index
,
313 wxObject
* userData
= NULL
);
314 inline wxSizerItem
* Insert( size_t index
,
320 wxObject
* userData
= NULL
);
321 inline wxSizerItem
* Insert( size_t index
,
323 const wxSizerFlags
& flags
);
324 inline wxSizerItem
* Insert( size_t index
,
326 const wxSizerFlags
& flags
);
327 virtual wxSizerItem
* Insert( size_t index
, wxSizerItem
*item
);
329 inline wxSizerItem
* InsertSpacer(size_t index
, int size
);
330 inline wxSizerItem
* InsertStretchSpacer(size_t index
, int prop
= 1);
332 inline wxSizerItem
* Prepend( wxWindow
*window
,
336 wxObject
* userData
= NULL
);
337 inline wxSizerItem
* Prepend( wxSizer
*sizer
,
341 wxObject
* userData
= NULL
);
342 inline wxSizerItem
* Prepend( int width
,
347 wxObject
* userData
= NULL
);
348 inline wxSizerItem
* Prepend( wxWindow
*window
, const wxSizerFlags
& flags
);
349 inline wxSizerItem
* Prepend( wxSizer
*sizer
, const wxSizerFlags
& flags
);
350 inline wxSizerItem
* Prepend( wxSizerItem
*item
);
352 inline wxSizerItem
* PrependSpacer(int size
);
353 inline wxSizerItem
* PrependStretchSpacer(int prop
= 1);
356 // Deprecated in 2.6 since historically it does not delete the window,
357 // use Detach instead.
358 wxDEPRECATED( virtual bool Remove( wxWindow
*window
) );
359 virtual bool Remove( wxSizer
*sizer
);
360 virtual bool Remove( int index
);
362 virtual bool Detach( wxWindow
*window
);
363 virtual bool Detach( wxSizer
*sizer
);
364 virtual bool Detach( int index
);
366 virtual void Clear( bool delete_windows
= false );
367 virtual void DeleteWindows();
369 void SetMinSize( int width
, int height
)
370 { DoSetMinSize( width
, height
); }
371 void SetMinSize( wxSize size
)
372 { DoSetMinSize( size
.x
, size
.y
); }
374 /* Searches recursively */
375 bool SetItemMinSize( wxWindow
*window
, int width
, int height
)
376 { return DoSetItemMinSize( window
, width
, height
); }
377 bool SetItemMinSize( wxWindow
*window
, wxSize size
)
378 { return DoSetItemMinSize( window
, size
.x
, size
.y
); }
380 /* Searches recursively */
381 bool SetItemMinSize( wxSizer
*sizer
, int width
, int height
)
382 { return DoSetItemMinSize( sizer
, width
, height
); }
383 bool SetItemMinSize( wxSizer
*sizer
, wxSize size
)
384 { return DoSetItemMinSize( sizer
, size
.x
, size
.y
); }
386 bool SetItemMinSize( size_t index
, int width
, int height
)
387 { return DoSetItemMinSize( index
, width
, height
); }
388 bool SetItemMinSize( size_t index
, wxSize size
)
389 { return DoSetItemMinSize( index
, size
.x
, size
.y
); }
391 wxSize
GetSize() const
393 wxPoint
GetPosition() const
394 { return m_position
; }
396 /* Calculate the minimal size or return m_minSize if bigger. */
399 virtual void RecalcSizes() = 0;
400 virtual wxSize
CalcMin() = 0;
402 virtual void Layout();
404 wxSize
Fit( wxWindow
*window
);
405 void FitInside( wxWindow
*window
);
406 void SetSizeHints( wxWindow
*window
);
407 void SetVirtualSizeHints( wxWindow
*window
);
409 wxSizerItemList
& GetChildren()
410 { return m_children
; }
412 void SetDimension( int x
, int y
, int width
, int height
);
414 wxSizerItem
* GetItem( wxWindow
*window
, bool recursive
= false );
415 wxSizerItem
* GetItem( wxSizer
*sizer
, bool recursive
= false );
416 wxSizerItem
* GetItem( size_t index
);
418 // Manage whether individual scene items are considered
419 // in the layout calculations or not.
420 bool Show( wxWindow
*window
, bool show
= true, bool recursive
= false );
421 bool Show( wxSizer
*sizer
, bool show
= true, bool recursive
= false );
422 bool Show( size_t index
, bool show
= true );
424 bool Hide( wxSizer
*sizer
, bool recursive
= false )
425 { return Show( sizer
, false, recursive
); }
426 bool Hide( wxWindow
*window
, bool recursive
= false )
427 { return Show( window
, false, recursive
); }
428 bool Hide( size_t index
)
429 { return Show( index
, false ); }
431 bool IsShown( wxWindow
*window
) const;
432 bool IsShown( wxSizer
*sizer
) const;
433 bool IsShown( size_t index
) const;
435 // Recursively call wxWindow::Show () on all sizer items.
436 virtual void ShowItems (bool show
);
442 wxSizerItemList m_children
;
444 wxSize
GetMaxWindowSize( wxWindow
*window
) const;
445 wxSize
GetMinWindowSize( wxWindow
*window
);
446 wxSize
GetMaxClientSize( wxWindow
*window
) const;
447 wxSize
GetMinClientSize( wxWindow
*window
);
448 wxSize
FitSize( wxWindow
*window
);
449 wxSize
VirtualFitSize( wxWindow
*window
);
451 virtual void DoSetMinSize( int width
, int height
);
452 virtual bool DoSetItemMinSize( wxWindow
*window
, int width
, int height
);
453 virtual bool DoSetItemMinSize( wxSizer
*sizer
, int width
, int height
);
454 virtual bool DoSetItemMinSize( size_t index
, int width
, int height
);
457 DECLARE_CLASS(wxSizer
)
460 //---------------------------------------------------------------------------
462 //---------------------------------------------------------------------------
464 class WXDLLEXPORT wxGridSizer
: public wxSizer
467 wxGridSizer( int rows
, int cols
, int vgap
, int hgap
);
468 wxGridSizer( int cols
, int vgap
= 0, int hgap
= 0 );
470 virtual void RecalcSizes();
471 virtual wxSize
CalcMin();
473 void SetCols( int cols
) { m_cols
= cols
; }
474 void SetRows( int rows
) { m_rows
= rows
; }
475 void SetVGap( int gap
) { m_vgap
= gap
; }
476 void SetHGap( int gap
) { m_hgap
= gap
; }
477 int GetCols() const { return m_cols
; }
478 int GetRows() const { return m_rows
; }
479 int GetVGap() const { return m_vgap
; }
480 int GetHGap() const { return m_hgap
; }
488 // return the number of total items and the number of columns and rows
489 int CalcRowsCols(int& rows
, int& cols
) const;
491 void SetItemBounds( wxSizerItem
*item
, int x
, int y
, int w
, int h
);
494 DECLARE_CLASS(wxGridSizer
)
497 //---------------------------------------------------------------------------
499 //---------------------------------------------------------------------------
501 // the bevaiour for resizing wxFlexGridSizer cells in the "non-flexible"
503 enum wxFlexSizerGrowMode
505 // don't resize the cells in non-flexible direction at all
506 wxFLEX_GROWMODE_NONE
,
508 // uniformly resize only the specified ones (default)
509 wxFLEX_GROWMODE_SPECIFIED
,
511 // uniformly resize all cells
515 class WXDLLEXPORT wxFlexGridSizer
: public wxGridSizer
519 wxFlexGridSizer( int rows
, int cols
, int vgap
, int hgap
);
520 wxFlexGridSizer( int cols
, int vgap
= 0, int hgap
= 0 );
521 virtual ~wxFlexGridSizer();
524 // set the rows/columns which will grow (the others will remain of the
525 // constant initial size)
526 void AddGrowableRow( size_t idx
, int proportion
= 0 );
527 void RemoveGrowableRow( size_t idx
);
528 void AddGrowableCol( size_t idx
, int proportion
= 0 );
529 void RemoveGrowableCol( size_t idx
);
532 // the sizer cells may grow in both directions, not grow at all or only
533 // grow in one direction but not the other
535 // the direction may be wxVERTICAL, wxHORIZONTAL or wxBOTH (default)
536 void SetFlexibleDirection(int direction
) { m_flexDirection
= direction
; }
537 int GetFlexibleDirection() const { return m_flexDirection
; }
539 // note that the grow mode only applies to the direction which is not
541 void SetNonFlexibleGrowMode(wxFlexSizerGrowMode mode
) { m_growMode
= mode
; }
542 wxFlexSizerGrowMode
GetNonFlexibleGrowMode() const { return m_growMode
; }
544 // Read-only access to the row heights and col widths arrays
545 const wxArrayInt
& GetRowHeights() const { return m_rowHeights
; }
546 const wxArrayInt
& GetColWidths() const { return m_colWidths
; }
549 virtual void RecalcSizes();
550 virtual wxSize
CalcMin();
553 void AdjustForFlexDirection();
554 void AdjustForGrowables(const wxSize
& sz
, const wxSize
& minsz
,
555 int nrows
, int ncols
);
557 // the heights/widths of all rows/columns
558 wxArrayInt m_rowHeights
,
561 // indices of the growable columns and rows
562 wxArrayInt m_growableRows
,
565 // proportion values of the corresponding growable rows and columns
566 wxArrayInt m_growableRowsProportions
,
567 m_growableColsProportions
;
569 // parameters describing whether the growable cells should be resized in
570 // both directions or only one
572 wxFlexSizerGrowMode m_growMode
;
574 // saves CalcMin result to optimize RecalcSizes
575 wxSize m_calculatedMinSize
;
578 DECLARE_CLASS(wxFlexGridSizer
)
579 DECLARE_NO_COPY_CLASS(wxFlexGridSizer
)
582 //---------------------------------------------------------------------------
584 //---------------------------------------------------------------------------
586 class WXDLLEXPORT wxBoxSizer
: public wxSizer
589 wxBoxSizer( int orient
);
594 int GetOrientation() const
597 void SetOrientation(int orient
)
598 { m_orient
= orient
; }
609 DECLARE_CLASS(wxBoxSizer
)
612 //---------------------------------------------------------------------------
614 //---------------------------------------------------------------------------
618 class WXDLLEXPORT wxStaticBox
;
620 class WXDLLEXPORT wxStaticBoxSizer
: public wxBoxSizer
623 wxStaticBoxSizer( wxStaticBox
*box
, int orient
);
628 wxStaticBox
*GetStaticBox() const
629 { return m_staticBox
; }
631 // override to hide/show the static box as well
632 virtual void ShowItems (bool show
);
635 wxStaticBox
*m_staticBox
;
638 DECLARE_CLASS(wxStaticBoxSizer
)
639 DECLARE_NO_COPY_CLASS(wxStaticBoxSizer
)
642 #endif // wxUSE_STATBOX
645 #if WXWIN_COMPATIBILITY_2_4
646 // NB: wxBookCtrlSizer and wxNotebookSizer are deprecated, they
647 // don't do anything. wxBookCtrl::DoGetBestSize does the job now.
649 // ----------------------------------------------------------------------------
651 // ----------------------------------------------------------------------------
655 // this sizer works with wxNotebook/wxListbook/... and sizes the control to
657 class WXDLLEXPORT wxBookCtrl
;
659 class WXDLLEXPORT wxBookCtrlSizer
: public wxSizer
662 wxDEPRECATED( wxBookCtrlSizer(wxBookCtrl
*bookctrl
) );
664 wxBookCtrl
*GetControl() const { return m_bookctrl
; }
666 virtual void RecalcSizes();
667 virtual wxSize
CalcMin();
670 // this protected ctor lets us mark the real one above as deprecated
671 // and still have warning-free build of the library itself:
674 wxBookCtrl
*m_bookctrl
;
677 DECLARE_CLASS(wxBookCtrlSizer
)
678 DECLARE_NO_COPY_CLASS(wxBookCtrlSizer
)
684 // before wxBookCtrl we only had wxNotebookSizer, keep it for backwards
686 class WXDLLEXPORT wxNotebook
;
688 class WXDLLEXPORT wxNotebookSizer
: public wxBookCtrlSizer
691 wxDEPRECATED( wxNotebookSizer(wxNotebook
*nb
) );
693 wxNotebook
*GetNotebook() const { return (wxNotebook
*)m_bookctrl
; }
696 DECLARE_CLASS(wxNotebookSizer
)
697 DECLARE_NO_COPY_CLASS(wxNotebookSizer
)
700 #endif // wxUSE_NOTEBOOK
702 #endif // wxUSE_BOOKCTRL
704 #endif // WXWIN_COMPATIBILITY_2_4
706 // ----------------------------------------------------------------------------
707 // inline functions implementation
708 // ----------------------------------------------------------------------------
711 wxSizer::Add( wxWindow
*window
, int proportion
, int flag
, int border
, wxObject
* userData
)
713 return Add( new wxSizerItem( window
, proportion
, flag
, border
, userData
) );
717 wxSizer::Add( wxSizer
*sizer
, int proportion
, int flag
, int border
, wxObject
* userData
)
719 return Add( new wxSizerItem( sizer
, proportion
, flag
, border
, userData
) );
723 wxSizer::Add( int width
, int height
, int proportion
, int flag
, int border
, wxObject
* userData
)
725 return Add( new wxSizerItem( width
, height
, proportion
, flag
, border
, userData
) );
729 wxSizer::Add( wxWindow
*window
, const wxSizerFlags
& flags
)
731 return Add( new wxSizerItem(window
, flags
) );
735 wxSizer::Add( wxSizer
*sizer
, const wxSizerFlags
& flags
)
737 return Add( new wxSizerItem(sizer
, flags
) );
741 wxSizer::Add( wxSizerItem
*item
)
743 return Insert( m_children
.GetCount(), item
);
747 wxSizer::AddSpacer(int size
)
749 return Add(size
, size
);
753 wxSizer::AddStretchSpacer(int prop
)
755 return Add(0, 0, prop
);
759 wxSizer::Prepend( wxWindow
*window
, int proportion
, int flag
, int border
, wxObject
* userData
)
761 return Prepend( new wxSizerItem( window
, proportion
, flag
, border
, userData
) );
765 wxSizer::Prepend( wxSizer
*sizer
, int proportion
, int flag
, int border
, wxObject
* userData
)
767 return Prepend( new wxSizerItem( sizer
, proportion
, flag
, border
, userData
) );
771 wxSizer::Prepend( int width
, int height
, int proportion
, int flag
, int border
, wxObject
* userData
)
773 return Prepend( new wxSizerItem( width
, height
, proportion
, flag
, border
, userData
) );
777 wxSizer::Prepend( wxSizerItem
*item
)
779 return Insert( 0, item
);
783 wxSizer::PrependSpacer(int size
)
785 return Prepend(size
, size
);
789 wxSizer::PrependStretchSpacer(int prop
)
791 return Prepend(0, 0, prop
);
795 wxSizer::Prepend( wxWindow
*window
, const wxSizerFlags
& flags
)
797 return Prepend( new wxSizerItem(window
, flags
) );
801 wxSizer::Prepend( wxSizer
*sizer
, const wxSizerFlags
& flags
)
803 return Prepend( new wxSizerItem(sizer
, flags
) );
807 wxSizer::Insert( size_t index
,
814 return Insert( index
, new wxSizerItem( window
, proportion
, flag
, border
, userData
) );
818 wxSizer::Insert( size_t index
,
825 return Insert( index
, new wxSizerItem( sizer
, proportion
, flag
, border
, userData
) );
829 wxSizer::Insert( size_t index
,
837 return Insert( index
, new wxSizerItem( width
, height
, proportion
, flag
, border
, userData
) );
841 wxSizer::Insert( size_t index
, wxWindow
*window
, const wxSizerFlags
& flags
)
843 return Insert( index
, new wxSizerItem(window
, flags
) );
847 wxSizer::Insert( size_t index
, wxSizer
*sizer
, const wxSizerFlags
& flags
)
849 return Insert( index
, new wxSizerItem(sizer
, flags
) );
853 wxSizer::InsertSpacer(size_t index
, int size
)
855 return Insert(index
, size
, size
);
859 wxSizer::InsertStretchSpacer(size_t index
, int prop
)
861 return Insert(index
, 0, 0, prop
);
865 #endif // __WXSIZER_H__