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 // ----------------------------------------------------------------------------
46 // Create the main frame window
47 MyFrame
*frame
= new MyFrame
;
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
59 EVT_MENU(LAYOUT_ABOUT
, MyFrame::OnAbout
)
60 EVT_MENU(LAYOUT_QUIT
, MyFrame::OnQuit
)
62 EVT_MENU(LAYOUT_TEST_SIZER
, MyFrame::TestFlexSizers
)
63 EVT_MENU(LAYOUT_TEST_NB_SIZER
, MyFrame::TestNotebookSizers
)
64 EVT_MENU(LAYOUT_TEST_GB_SIZER
, MyFrame::TestGridBagSizer
)
67 // Define my frame constructor
69 : wxFrame(NULL
, wxID_ANY
, _T("wxWidgets Layout Demo"),
70 wxDefaultPosition
, wxDefaultSize
,
71 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
74 wxMenu
*file_menu
= new wxMenu
;
76 file_menu
->Append(LAYOUT_TEST_SIZER
, _T("Test wx&FlexSizer"));
77 file_menu
->Append(LAYOUT_TEST_NB_SIZER
, _T("&Test notebook sizers"));
78 file_menu
->Append(LAYOUT_TEST_GB_SIZER
, _T("Test &gridbag sizer"));
80 file_menu
->AppendSeparator();
81 file_menu
->Append(LAYOUT_QUIT
, _T("E&xit"), _T("Quit program"));
83 wxMenu
*help_menu
= new wxMenu
;
84 help_menu
->Append(LAYOUT_ABOUT
, _T("&About"), _T("About layout demo"));
86 wxMenuBar
*menu_bar
= new wxMenuBar
;
88 menu_bar
->Append(file_menu
, _T("&File"));
89 menu_bar
->Append(help_menu
, _T("&Help"));
91 // Associate the menu bar with the frame
96 SetStatusText(_T("wxWidgets layout demo"));
97 #endif // wxUSE_STATUSBAR
99 // we want to get a dialog that is stretchable because it
100 // has a text ctrl in the middle. at the bottom, we have
101 // two buttons which.
103 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
105 // 1) top: create wxStaticText with minimum size equal to its default size
107 new wxStaticText( this, wxID_ANY
, _T("An explanation (wxALIGN_RIGHT).") ),
108 0, // make vertically unstretchable
109 wxALIGN_RIGHT
| // right align text
110 wxTOP
| wxLEFT
| wxRIGHT
, // make border all around except wxBOTTOM
111 5 ); // set border width to 5
113 // 2) top: create wxTextCtrl with minimum size (100x60)
115 new wxTextCtrl( this, wxID_ANY
, _T("My text (wxEXPAND)."), wxDefaultPosition
, wxSize(100,60), wxTE_MULTILINE
),
116 1, // make vertically stretchable
117 wxEXPAND
| // make horizontally stretchable
118 wxALL
, // and make border all around
119 5 ); // set border width to 5
121 // 2.5) Gratuitous test of wxStaticBoxSizers
122 wxBoxSizer
*statsizer
= new wxStaticBoxSizer(
123 new wxStaticBox(this, wxID_ANY
, _T("A wxStaticBoxSizer")),
126 new wxStaticText(this, wxID_ANY
, _T("And some TEXT inside it")),
131 topsizer
->Add(statsizer
, 1, wxEXPAND
| wxALL
, 10);
133 // 2.7) And a test of wxGridSizer
134 wxGridSizer
*gridsizer
= new wxGridSizer(2, 5, 5);
135 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Label")), 0,
136 wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
);
137 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("Grid sizer demo")), 1,
138 wxGROW
| wxALIGN_CENTER_VERTICAL
);
139 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Another label")), 0,
140 wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
);
141 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("More text")), 1,
142 wxGROW
| wxALIGN_CENTER_VERTICAL
);
143 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Final label")), 0,
144 wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
);
145 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("And yet more text")), 1,
146 wxGROW
| wxALIGN_CENTER_VERTICAL
);
147 topsizer
->Add(gridsizer
, 1, wxGROW
| wxALL
, 10);
151 // 3) middle: create wxStaticLine with minimum size (3x3)
153 new wxStaticLine( this, wxID_ANY
, wxDefaultPosition
, wxSize(3,3), wxHORIZONTAL
),
154 0, // make vertically unstretchable
155 wxEXPAND
| // make horizontally stretchable
156 wxALL
, // and make border all around
157 5 ); // set border width to 5
158 #endif // wxUSE_STATLINE
161 // 4) bottom: create two centred wxButtons
162 wxBoxSizer
*button_box
= new wxBoxSizer( wxHORIZONTAL
);
164 new wxButton( this, wxID_ANY
, _T("Two buttons in a box") ),
165 0, // make horizontally unstretchable
166 wxALL
, // make border all around
167 7 ); // set border width to 7
169 new wxButton( this, wxID_ANY
, _T("(wxCENTER)") ),
170 0, // make horizontally unstretchable
171 wxALL
, // make border all around
172 7 ); // set border width to 7
176 0, // make vertically unstretchable
177 wxCENTER
); // no border and centre horizontally
179 // don't allow frame to get smaller than what the sizers tell it and also set
180 // the initial size as calculated by the sizers
181 topsizer
->SetSizeHints( this );
183 SetSizer( topsizer
);
186 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
) )
191 void MyFrame::TestFlexSizers(wxCommandEvent
& WXUNUSED(event
) )
193 MyFlexSizerFrame
*newFrame
= new MyFlexSizerFrame(_T("Flex Sizer Test Frame"), 50, 50);
194 newFrame
->Show(true);
197 void MyFrame::TestNotebookSizers(wxCommandEvent
& WXUNUSED(event
) )
199 MySizerDialog
dialog( this, _T("Notebook Sizer Test Dialog") );
205 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
) )
207 (void)wxMessageBox(_T("wxWidgets GUI library layout demo\n"),
208 _T("About Layout Demo"), wxOK
|wxICON_INFORMATION
);
211 void MyFrame::TestGridBagSizer(wxCommandEvent
& WXUNUSED(event
) )
213 MyGridBagSizerFrame
*newFrame
= new
214 MyGridBagSizerFrame(_T("wxGridBagSizer Test Frame"), 50, 50);
215 newFrame
->Show(true);
219 // ----------------------------------------------------------------------------
221 // ----------------------------------------------------------------------------
223 void MyFlexSizerFrame::InitFlexSizer(wxFlexGridSizer
*sizer
)
225 for ( int i
= 0; i
< 3; i
++ )
227 for ( int j
= 0; j
< 3; j
++ )
229 sizer
->Add(new wxStaticText
233 wxString::Format(_T("(%d, %d)"), i
+ 1, j
+ 1),
238 0, wxEXPAND
| wxALIGN_CENTER_VERTICAL
| wxALL
, 3);
243 MyFlexSizerFrame::MyFlexSizerFrame(const wxChar
*title
, int x
, int y
)
244 : wxFrame(NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
246 wxFlexGridSizer
*sizerFlex
;
248 // consttuct the first column
249 wxSizer
*sizerCol1
= new wxBoxSizer(wxVERTICAL
);
250 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Ungrowable:")), 0, wxCENTER
| wxTOP
, 20);
251 sizerFlex
= new wxFlexGridSizer(3, 3);
252 InitFlexSizer(sizerFlex
);
253 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
255 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle column:")), 0, wxCENTER
| wxTOP
, 20);
256 sizerFlex
= new wxFlexGridSizer(3, 3);
257 InitFlexSizer(sizerFlex
);
258 sizerFlex
->AddGrowableCol(1);
259 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
261 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle row:")), 0, wxCENTER
| wxTOP
, 20);
262 sizerFlex
= new wxFlexGridSizer(3, 3);
263 InitFlexSizer(sizerFlex
);
264 sizerFlex
->AddGrowableRow(1);
265 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
267 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("All growable columns:")), 0, wxCENTER
| wxTOP
, 20);
268 sizerFlex
= new wxFlexGridSizer(3, 3);
269 InitFlexSizer(sizerFlex
);
270 sizerFlex
->AddGrowableCol(0, 1);
271 sizerFlex
->AddGrowableCol(1, 2);
272 sizerFlex
->AddGrowableCol(2, 3);
273 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
276 wxSizer
*sizerCol2
= new wxBoxSizer(wxVERTICAL
);
277 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle row and column:")), 0, wxCENTER
| wxTOP
, 20);
278 sizerFlex
= new wxFlexGridSizer(3, 3);
279 InitFlexSizer(sizerFlex
);
280 sizerFlex
->AddGrowableCol(1);
281 sizerFlex
->AddGrowableRow(1);
282 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
284 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with horz flex direction")), 0, wxCENTER
| wxTOP
, 20);
285 sizerFlex
= new wxFlexGridSizer(3, 3);
286 InitFlexSizer(sizerFlex
);
287 sizerFlex
->AddGrowableCol(1);
288 sizerFlex
->AddGrowableRow(1);
289 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
290 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
292 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with grow mode == \"none\"")), 0, wxCENTER
| wxTOP
, 20);
293 sizerFlex
= new wxFlexGridSizer(3, 3);
294 InitFlexSizer(sizerFlex
);
295 sizerFlex
->AddGrowableCol(1);
296 sizerFlex
->AddGrowableRow(1);
297 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
298 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_NONE
);
299 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
301 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with grow mode == \"all\"")), 0, wxCENTER
| wxTOP
, 20);
302 sizerFlex
= new wxFlexGridSizer(3, 3);
303 InitFlexSizer(sizerFlex
);
304 sizerFlex
->AddGrowableCol(1);
305 sizerFlex
->AddGrowableRow(1);
306 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
307 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_ALL
);
308 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
310 // add both columns to grid sizer
311 wxGridSizer
*sizerTop
= new wxGridSizer(2, 0, 20);
312 sizerTop
->Add(sizerCol1
, 1, wxEXPAND
);
313 sizerTop
->Add(sizerCol2
, 1, wxEXPAND
);
316 sizerTop
->SetSizeHints(this);
319 // ----------------------------------------------------------------------------
321 // ----------------------------------------------------------------------------
323 MySizerDialog::MySizerDialog(wxWindow
*parent
, const wxChar
*title
)
324 : wxDialog(parent
, wxID_ANY
, wxString(title
))
326 // Begin with first hierarchy: a notebook at the top and
327 // and OK button at the bottom.
329 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
331 wxNotebook
*notebook
= new wxNotebook( this, wxID_ANY
);
332 topsizer
->Add( notebook
, 1, wxGROW
);
334 wxButton
*button
= new wxButton( this, wxID_OK
, _T("OK") );
335 topsizer
->Add( button
, 0, wxALIGN_RIGHT
| wxALL
, 10 );
337 // First page: one big text ctrl
338 wxTextCtrl
*multi
= new wxTextCtrl( notebook
, wxID_ANY
, _T("TextCtrl."), wxDefaultPosition
, wxDefaultSize
, wxTE_MULTILINE
);
339 notebook
->AddPage( multi
, _T("Page One") );
341 // Second page: a text ctrl and a button
342 wxPanel
*panel
= new wxPanel( notebook
, wxID_ANY
);
343 notebook
->AddPage( panel
, _T("Page Two") );
345 wxSizer
*panelsizer
= new wxBoxSizer( wxVERTICAL
);
347 wxTextCtrl
*text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 1."), wxDefaultPosition
, wxSize(250,-1) );
348 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
349 text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 2."), wxDefaultPosition
, wxSize(250,-1) );
350 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
351 wxButton
*button2
= new wxButton( panel
, wxID_ANY
, _T("Hallo") );
352 panelsizer
->Add( button2
, 0, wxALIGN_RIGHT
| wxLEFT
|wxRIGHT
|wxBOTTOM
, 30 );
354 panel
->SetAutoLayout( true );
355 panel
->SetSizer( panelsizer
);
357 // Tell dialog to use sizer
358 SetSizer( topsizer
);
359 topsizer
->SetSizeHints( this );
362 // ----------------------------------------------------------------------------
363 // MyGridBagSizerFrame
364 // ----------------------------------------------------------------------------
366 // some simple macros to help make the sample code below more clear
367 #define TEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text))
368 #define MLTEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE)
369 #define POS(r, c) wxGBPosition(r,c)
370 #define SPAN(r, c) wxGBSpan(r,c)
372 wxChar
* gbsDescription
=_T("\
373 The wxGridBagSizer is similar to the wxFlexGridSizer except the items are explicitly positioned\n\
374 in a virtual cell of the layout grid, and column or row spanning is allowed. For example, this\n\
375 static text is positioned at (0,0) and it spans 7 columns.");
389 BEGIN_EVENT_TABLE(MyGridBagSizerFrame
, wxFrame
)
390 EVT_BUTTON( GBS_HIDE_BTN
, MyGridBagSizerFrame::OnHideBtn
)
391 EVT_BUTTON( GBS_SHOW_BTN
, MyGridBagSizerFrame::OnShowBtn
)
392 EVT_BUTTON( GBS_MOVE_BTN1
, MyGridBagSizerFrame::OnMoveBtn
)
393 EVT_BUTTON( GBS_MOVE_BTN2
, MyGridBagSizerFrame::OnMoveBtn
)
397 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar
*title
, int x
, int y
)
398 : wxFrame( NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
400 wxPanel
* p
= new wxPanel(this, wxID_ANY
);
402 m_gbs
= new wxGridBagSizer();
405 m_gbs
->Add( new wxStaticText(p
, wxID_ANY
, gbsDescription
),
406 POS(0,0), SPAN(1, 7),
407 wxALIGN_CENTER
| wxALL
, 5);
409 m_gbs
->Add( TEXTCTRL("pos(1,0)"), POS(1,0) );
410 m_gbs
->Add( TEXTCTRL("pos(1,1)"), POS(1,1) );
411 m_gbs
->Add( TEXTCTRL("pos(2,0)"), POS(2,0) );
412 m_gbs
->Add( TEXTCTRL("pos(2,1)"), POS(2,1) );
413 m_gbs
->Add( MLTEXTCTRL("pos(3,2), span(1,2)\nthis row and col are growable"),
414 POS(3,2), SPAN(1,2), wxEXPAND
);
415 m_gbs
->Add( MLTEXTCTRL("pos(4,3)\nspan(3,1)"),
416 POS(4,3), SPAN(3,1), wxEXPAND
);
417 m_gbs
->Add( TEXTCTRL("pos(5,4)"), POS(5,4), wxDefaultSpan
, wxEXPAND
);
418 m_gbs
->Add( TEXTCTRL("pos(6,5)"), POS(6,5), wxDefaultSpan
, wxEXPAND
);
419 m_gbs
->Add( TEXTCTRL("pos(7,6)"), POS(7,6) );
421 //m_gbs->Add( TEXTCTRL("bad position"), POS(4,3) ); // Test for assert
422 //m_gbs->Add( TEXTCTRL("bad position"), POS(5,3) ); // Test for assert
425 m_moveBtn1
= new wxButton(p
, GBS_MOVE_BTN1
, _T("Move this to (3,6)"));
426 m_moveBtn2
= new wxButton(p
, GBS_MOVE_BTN2
, _T("Move this to (3,6)"));
427 m_gbs
->Add( m_moveBtn1
, POS(10,2) );
428 m_gbs
->Add( m_moveBtn2
, POS(10,3) );
430 m_hideBtn
= new wxButton(p
, GBS_HIDE_BTN
, _T("Hide this item -->"));
431 m_gbs
->Add(m_hideBtn
, POS(12, 3));
433 m_hideTxt
= new wxTextCtrl(p
, wxID_ANY
, _T("pos(12,4), size(150, -1)"),
434 wxDefaultPosition
, wxSize(150,-1));
435 m_gbs
->Add( m_hideTxt
, POS(12,4) );
437 m_showBtn
= new wxButton(p
, GBS_SHOW_BTN
, _T("<-- Show it again"));
438 m_gbs
->Add(m_showBtn
, POS(12, 5));
439 m_showBtn
->Disable();
441 m_gbs
->Add(10,10, POS(14,0));
443 m_gbs
->AddGrowableRow(3);
444 m_gbs
->AddGrowableCol(2);
446 p
->SetSizerAndFit(m_gbs
);
447 SetClientSize(p
->GetSize());
451 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent
&)
453 m_gbs
->Hide(m_hideTxt
);
454 m_hideBtn
->Disable();
459 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent
&)
461 m_gbs
->Show(m_hideTxt
);
463 m_showBtn
->Disable();
468 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent
& event
)
470 wxButton
* btn
= (wxButton
*)event
.GetEventObject();
471 wxGBPosition curPos
= m_gbs
->GetItemPosition(btn
);
473 // if it's already at the "other" spot then move it back
474 if (curPos
== wxGBPosition(3,6))
476 m_gbs
->SetItemPosition(btn
, m_lastPos
);
477 btn
->SetLabel(_T("Move this to (3,6)"));
481 if ( m_gbs
->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
483 _T("wxGridBagSizer will not allow items to be in the same cell as\n\
484 another item, so this operation will fail. You will also get an assert\n\
485 when compiled in debug mode."), _T("Warning"), wxOK
| wxICON_INFORMATION
);
487 if ( m_gbs
->SetItemPosition(btn
, wxGBPosition(3,6)) )
490 btn
->SetLabel(_T("Move it back"));