1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Layout sample
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // ----------------------------------------------------------------------------
14 // ----------------------------------------------------------------------------
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
28 #include "wx/gbsizer.h"
29 #include "wx/statline.h"
30 #include "wx/notebook.h"
34 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
42 // Create the main frame window
43 MyFrame
*frame
= new MyFrame
;
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
55 EVT_MENU(LAYOUT_ABOUT
, MyFrame::OnAbout
)
56 EVT_MENU(LAYOUT_QUIT
, MyFrame::OnQuit
)
58 EVT_MENU(LAYOUT_TEST_SIZER
, MyFrame::TestFlexSizers
)
59 EVT_MENU(LAYOUT_TEST_NB_SIZER
, MyFrame::TestNotebookSizers
)
60 EVT_MENU(LAYOUT_TEST_GB_SIZER
, MyFrame::TestGridBagSizer
)
63 // Define my frame constructor
65 : wxFrame(NULL
, wxID_ANY
, _T("wxWidgets Layout Demo"),
66 wxDefaultPosition
, wxDefaultSize
,
67 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
70 wxMenu
*file_menu
= new wxMenu
;
72 file_menu
->Append(LAYOUT_TEST_SIZER
, _T("Test wx&FlexSizer"));
73 file_menu
->Append(LAYOUT_TEST_NB_SIZER
, _T("&Test notebook sizers"));
74 file_menu
->Append(LAYOUT_TEST_GB_SIZER
, _T("Test &gridbag sizer"));
76 file_menu
->AppendSeparator();
77 file_menu
->Append(LAYOUT_QUIT
, _T("E&xit"), _T("Quit program"));
79 wxMenu
*help_menu
= new wxMenu
;
80 help_menu
->Append(LAYOUT_ABOUT
, _T("&About"), _T("About layout demo"));
82 wxMenuBar
*menu_bar
= new wxMenuBar
;
84 menu_bar
->Append(file_menu
, _T("&File"));
85 menu_bar
->Append(help_menu
, _T("&Help"));
87 // Associate the menu bar with the frame
92 SetStatusText(_T("wxWidgets layout demo"));
93 #endif // wxUSE_STATUSBAR
95 // we want to get a dialog that is stretchable because it
96 // has a text ctrl in the middle. at the bottom, we have
99 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
101 // 1) top: create wxStaticText with minimum size equal to its default size
103 new wxStaticText( this, wxID_ANY
, _T("An explanation (wxALIGN_RIGHT).") ),
104 wxSizerFlags().Align(wxALIGN_RIGHT
).Border(wxALL
& ~wxBOTTOM
, 5));
106 // 2) top: create wxTextCtrl with minimum size (100x60)
108 new wxTextCtrl( this, wxID_ANY
, _T("My text (wxEXPAND)."), wxDefaultPosition
, wxSize(100,60), wxTE_MULTILINE
),
109 wxSizerFlags(1).Expand().Border(wxALL
, 5));
111 // 2.5) Gratuitous test of wxStaticBoxSizers
112 wxBoxSizer
*statsizer
= new wxStaticBoxSizer(
113 new wxStaticBox(this, wxID_ANY
, _T("A wxStaticBoxSizer")), wxVERTICAL
);
115 new wxStaticText(this, wxID_ANY
, _T("And some TEXT inside it")),
116 wxSizerFlags().Center().Border(wxALL
, 30));
119 wxSizerFlags(1).Expand().Border(wxALL
, 10));
121 // 2.7) And a test of wxGridSizer
122 wxGridSizer
*gridsizer
= new wxGridSizer(2, 5, 5);
123 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Label")),
124 wxSizerFlags().Align(wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
));
125 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("Grid sizer demo")),
126 wxSizerFlags(1).Align(wxGROW
| wxALIGN_CENTER_VERTICAL
));
127 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Another label")),
128 wxSizerFlags().Align(wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
));
129 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("More text")),
130 wxSizerFlags(1).Align(wxGROW
| wxALIGN_CENTER_VERTICAL
));
131 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Final label")),
132 wxSizerFlags().Align(wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
));
133 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("And yet more text")),
134 wxSizerFlags().Align(wxGROW
| wxALIGN_CENTER_VERTICAL
));
137 wxSizerFlags().Proportion(1).Expand().Border(wxALL
, 10));
141 // 3) middle: create wxStaticLine with minimum size (3x3)
143 new wxStaticLine( this, wxID_ANY
, wxDefaultPosition
, wxSize(3,3), wxHORIZONTAL
),
144 wxSizerFlags().Expand());
145 #endif // wxUSE_STATLINE
148 // 4) bottom: create two centred wxButtons
149 wxBoxSizer
*button_box
= new wxBoxSizer( wxHORIZONTAL
);
151 new wxButton( this, wxID_ANY
, _T("Two buttons in a box") ),
152 wxSizerFlags().Border(wxALL
, 7));
154 new wxButton( this, wxID_ANY
, _T("(wxCENTER)") ),
155 wxSizerFlags().Border(wxALL
, 7));
157 topsizer
->Add(button_box
, wxSizerFlags().Center());
159 // don't allow frame to get smaller than what the sizers tell it and also set
160 // the initial size as calculated by the sizers
161 topsizer
->SetSizeHints( this );
163 SetSizer( topsizer
);
166 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
) )
171 void MyFrame::TestFlexSizers(wxCommandEvent
& WXUNUSED(event
) )
173 MyFlexSizerFrame
*newFrame
= new MyFlexSizerFrame(_T("Flex Sizer Test Frame"), 50, 50);
174 newFrame
->Show(true);
177 void MyFrame::TestNotebookSizers(wxCommandEvent
& WXUNUSED(event
) )
179 MySizerDialog
dialog( this, _T("Notebook Sizer Test Dialog") );
185 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
) )
187 (void)wxMessageBox(_T("wxWidgets GUI library layout demo\n"),
188 _T("About Layout Demo"), wxOK
|wxICON_INFORMATION
);
191 void MyFrame::TestGridBagSizer(wxCommandEvent
& WXUNUSED(event
) )
193 MyGridBagSizerFrame
*newFrame
= new
194 MyGridBagSizerFrame(_T("wxGridBagSizer Test Frame"), 50, 50);
195 newFrame
->Show(true);
199 // ----------------------------------------------------------------------------
201 // ----------------------------------------------------------------------------
203 void MyFlexSizerFrame::InitFlexSizer(wxFlexGridSizer
*sizer
)
205 for ( int i
= 0; i
< 3; i
++ )
207 for ( int j
= 0; j
< 3; j
++ )
209 sizer
->Add(new wxStaticText
213 wxString::Format(_T("(%d, %d)"), i
+ 1, j
+ 1),
218 0, wxEXPAND
| wxALIGN_CENTER_VERTICAL
| wxALL
, 3);
223 MyFlexSizerFrame::MyFlexSizerFrame(const wxChar
*title
, int x
, int y
)
224 : wxFrame(NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
226 wxFlexGridSizer
*sizerFlex
;
228 // consttuct the first column
229 wxSizer
*sizerCol1
= new wxBoxSizer(wxVERTICAL
);
230 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Ungrowable:")), 0, wxCENTER
| wxTOP
, 20);
231 sizerFlex
= new wxFlexGridSizer(3, 3);
232 InitFlexSizer(sizerFlex
);
233 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
235 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle column:")), 0, wxCENTER
| wxTOP
, 20);
236 sizerFlex
= new wxFlexGridSizer(3, 3);
237 InitFlexSizer(sizerFlex
);
238 sizerFlex
->AddGrowableCol(1);
239 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
241 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle row:")), 0, wxCENTER
| wxTOP
, 20);
242 sizerFlex
= new wxFlexGridSizer(3, 3);
243 InitFlexSizer(sizerFlex
);
244 sizerFlex
->AddGrowableRow(1);
245 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
247 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("All growable columns:")), 0, wxCENTER
| wxTOP
, 20);
248 sizerFlex
= new wxFlexGridSizer(3, 3);
249 InitFlexSizer(sizerFlex
);
250 sizerFlex
->AddGrowableCol(0, 1);
251 sizerFlex
->AddGrowableCol(1, 2);
252 sizerFlex
->AddGrowableCol(2, 3);
253 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
256 wxSizer
*sizerCol2
= new wxBoxSizer(wxVERTICAL
);
257 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle row and column:")), 0, wxCENTER
| wxTOP
, 20);
258 sizerFlex
= new wxFlexGridSizer(3, 3);
259 InitFlexSizer(sizerFlex
);
260 sizerFlex
->AddGrowableCol(1);
261 sizerFlex
->AddGrowableRow(1);
262 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
264 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with horz flex direction")), 0, wxCENTER
| wxTOP
, 20);
265 sizerFlex
= new wxFlexGridSizer(3, 3);
266 InitFlexSizer(sizerFlex
);
267 sizerFlex
->AddGrowableCol(1);
268 sizerFlex
->AddGrowableRow(1);
269 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
270 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
272 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with grow mode == \"none\"")), 0, wxCENTER
| wxTOP
, 20);
273 sizerFlex
= new wxFlexGridSizer(3, 3);
274 InitFlexSizer(sizerFlex
);
275 sizerFlex
->AddGrowableCol(1);
276 sizerFlex
->AddGrowableRow(1);
277 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
278 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_NONE
);
279 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
281 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with grow mode == \"all\"")), 0, wxCENTER
| wxTOP
, 20);
282 sizerFlex
= new wxFlexGridSizer(3, 3);
283 InitFlexSizer(sizerFlex
);
284 sizerFlex
->AddGrowableCol(1);
285 sizerFlex
->AddGrowableRow(1);
286 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
287 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_ALL
);
288 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
290 // add both columns to grid sizer
291 wxGridSizer
*sizerTop
= new wxGridSizer(2, 0, 20);
292 sizerTop
->Add(sizerCol1
, 1, wxEXPAND
);
293 sizerTop
->Add(sizerCol2
, 1, wxEXPAND
);
296 sizerTop
->SetSizeHints(this);
299 // ----------------------------------------------------------------------------
301 // ----------------------------------------------------------------------------
303 MySizerDialog::MySizerDialog(wxWindow
*parent
, const wxChar
*title
)
304 : wxDialog(parent
, wxID_ANY
, wxString(title
))
306 // Begin with first hierarchy: a notebook at the top and
307 // and OK button at the bottom.
309 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
311 wxNotebook
*notebook
= new wxNotebook( this, wxID_ANY
);
312 topsizer
->Add( notebook
, 1, wxGROW
);
314 wxButton
*button
= new wxButton( this, wxID_OK
, _T("OK") );
315 topsizer
->Add( button
, 0, wxALIGN_RIGHT
| wxALL
, 10 );
317 // First page: one big text ctrl
318 wxTextCtrl
*multi
= new wxTextCtrl( notebook
, wxID_ANY
, _T("TextCtrl."), wxDefaultPosition
, wxDefaultSize
, wxTE_MULTILINE
);
319 notebook
->AddPage( multi
, _T("Page One") );
321 // Second page: a text ctrl and a button
322 wxPanel
*panel
= new wxPanel( notebook
, wxID_ANY
);
323 notebook
->AddPage( panel
, _T("Page Two") );
325 wxSizer
*panelsizer
= new wxBoxSizer( wxVERTICAL
);
327 wxTextCtrl
*text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 1."), wxDefaultPosition
, wxSize(250,-1) );
328 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
329 text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 2."), wxDefaultPosition
, wxSize(250,-1) );
330 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
331 wxButton
*button2
= new wxButton( panel
, wxID_ANY
, _T("Hallo") );
332 panelsizer
->Add( button2
, 0, wxALIGN_RIGHT
| wxLEFT
|wxRIGHT
|wxBOTTOM
, 30 );
334 panel
->SetAutoLayout( true );
335 panel
->SetSizer( panelsizer
);
337 // Tell dialog to use sizer
338 SetSizer( topsizer
);
339 topsizer
->SetSizeHints( this );
342 // ----------------------------------------------------------------------------
343 // MyGridBagSizerFrame
344 // ----------------------------------------------------------------------------
346 // some simple macros to help make the sample code below more clear
347 #define TEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text))
348 #define MLTEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE)
349 #define POS(r, c) wxGBPosition(r,c)
350 #define SPAN(r, c) wxGBSpan(r,c)
352 wxChar
* gbsDescription
=_T("\
353 The wxGridBagSizer is similar to the wxFlexGridSizer except the items are explicitly positioned\n\
354 in a virtual cell of the layout grid, and column or row spanning is allowed. For example, this\n\
355 static text is positioned at (0,0) and it spans 7 columns.");
369 BEGIN_EVENT_TABLE(MyGridBagSizerFrame
, wxFrame
)
370 EVT_BUTTON( GBS_HIDE_BTN
, MyGridBagSizerFrame::OnHideBtn
)
371 EVT_BUTTON( GBS_SHOW_BTN
, MyGridBagSizerFrame::OnShowBtn
)
372 EVT_BUTTON( GBS_MOVE_BTN1
, MyGridBagSizerFrame::OnMoveBtn
)
373 EVT_BUTTON( GBS_MOVE_BTN2
, MyGridBagSizerFrame::OnMoveBtn
)
377 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar
*title
, int x
, int y
)
378 : wxFrame( NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
380 wxPanel
* p
= new wxPanel(this, wxID_ANY
);
382 m_gbs
= new wxGridBagSizer();
385 m_gbs
->Add( new wxStaticText(p
, wxID_ANY
, gbsDescription
),
386 POS(0,0), SPAN(1, 7),
387 wxALIGN_CENTER
| wxALL
, 5);
389 m_gbs
->Add( TEXTCTRL("pos(1,0)"), POS(1,0) );
390 m_gbs
->Add( TEXTCTRL("pos(1,1)"), POS(1,1) );
391 m_gbs
->Add( TEXTCTRL("pos(2,0)"), POS(2,0) );
392 m_gbs
->Add( TEXTCTRL("pos(2,1)"), POS(2,1) );
393 m_gbs
->Add( MLTEXTCTRL("pos(3,2), span(1,2)\nthis row and col are growable"),
394 POS(3,2), SPAN(1,2), wxEXPAND
);
395 m_gbs
->Add( MLTEXTCTRL("pos(4,3)\nspan(3,1)"),
396 POS(4,3), SPAN(3,1), wxEXPAND
);
397 m_gbs
->Add( TEXTCTRL("pos(5,4)"), POS(5,4), wxDefaultSpan
, wxEXPAND
);
398 m_gbs
->Add( TEXTCTRL("pos(6,5)"), POS(6,5), wxDefaultSpan
, wxEXPAND
);
399 m_gbs
->Add( TEXTCTRL("pos(7,6)"), POS(7,6) );
401 //m_gbs->Add( TEXTCTRL("bad position"), POS(4,3) ); // Test for assert
402 //m_gbs->Add( TEXTCTRL("bad position"), POS(5,3) ); // Test for assert
405 m_moveBtn1
= new wxButton(p
, GBS_MOVE_BTN1
, _T("Move this to (3,6)"));
406 m_moveBtn2
= new wxButton(p
, GBS_MOVE_BTN2
, _T("Move this to (3,6)"));
407 m_gbs
->Add( m_moveBtn1
, POS(10,2) );
408 m_gbs
->Add( m_moveBtn2
, POS(10,3) );
410 m_hideBtn
= new wxButton(p
, GBS_HIDE_BTN
, _T("Hide this item -->"));
411 m_gbs
->Add(m_hideBtn
, POS(12, 3));
413 m_hideTxt
= new wxTextCtrl(p
, wxID_ANY
, _T("pos(12,4), size(150, -1)"),
414 wxDefaultPosition
, wxSize(150,-1));
415 m_gbs
->Add( m_hideTxt
, POS(12,4) );
417 m_showBtn
= new wxButton(p
, GBS_SHOW_BTN
, _T("<-- Show it again"));
418 m_gbs
->Add(m_showBtn
, POS(12, 5));
419 m_showBtn
->Disable();
421 m_gbs
->Add(10,10, POS(14,0));
423 m_gbs
->AddGrowableRow(3);
424 m_gbs
->AddGrowableCol(2);
426 p
->SetSizerAndFit(m_gbs
);
427 SetClientSize(p
->GetSize());
431 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent
&)
433 m_gbs
->Hide(m_hideTxt
);
434 m_hideBtn
->Disable();
439 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent
&)
441 m_gbs
->Show(m_hideTxt
);
443 m_showBtn
->Disable();
448 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent
& event
)
450 wxButton
* btn
= (wxButton
*)event
.GetEventObject();
451 wxGBPosition curPos
= m_gbs
->GetItemPosition(btn
);
453 // if it's already at the "other" spot then move it back
454 if (curPos
== wxGBPosition(3,6))
456 m_gbs
->SetItemPosition(btn
, m_lastPos
);
457 btn
->SetLabel(_T("Move this to (3,6)"));
461 if ( m_gbs
->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
463 _T("wxGridBagSizer will not allow items to be in the same cell as\n\
464 another item, so this operation will fail. You will also get an assert\n\
465 when compiled in debug mode."), _T("Warning"), wxOK
| wxICON_INFORMATION
);
467 if ( m_gbs
->SetItemPosition(btn
, wxGBPosition(3,6)) )
470 btn
->SetLabel(_T("Move it back"));