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);
150 // 3) middle: create wxStaticLine with minimum size (3x3)
152 new wxStaticLine( this, wxID_ANY
, wxDefaultPosition
, wxSize(3,3), wxHORIZONTAL
),
153 0, // make vertically unstretchable
154 wxEXPAND
| // make horizontally stretchable
155 wxALL
, // and make border all around
156 5 ); // set border width to 5
159 // 4) bottom: create two centred wxButtons
160 wxBoxSizer
*button_box
= new wxBoxSizer( wxHORIZONTAL
);
162 new wxButton( this, wxID_ANY
, _T("Two buttons in a box") ),
163 0, // make horizontally unstretchable
164 wxALL
, // make border all around
165 7 ); // set border width to 7
167 new wxButton( this, wxID_ANY
, _T("(wxCENTER)") ),
168 0, // make horizontally unstretchable
169 wxALL
, // make border all around
170 7 ); // set border width to 7
174 0, // make vertically unstretchable
175 wxCENTER
); // no border and centre horizontally
177 // don't allow frame to get smaller than what the sizers tell it and also set
178 // the initial size as calculated by the sizers
179 topsizer
->SetSizeHints( this );
181 SetSizer( topsizer
);
184 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
) )
189 void MyFrame::TestFlexSizers(wxCommandEvent
& WXUNUSED(event
) )
191 MyFlexSizerFrame
*newFrame
= new MyFlexSizerFrame(_T("Flex Sizer Test Frame"), 50, 50);
192 newFrame
->Show(true);
195 void MyFrame::TestNotebookSizers(wxCommandEvent
& WXUNUSED(event
) )
197 MySizerDialog
dialog( this, _T("Notebook Sizer Test Dialog") );
203 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
) )
205 (void)wxMessageBox(_T("wxWidgets GUI library layout demo\n"),
206 _T("About Layout Demo"), wxOK
|wxICON_INFORMATION
);
209 void MyFrame::TestGridBagSizer(wxCommandEvent
& WXUNUSED(event
) )
211 MyGridBagSizerFrame
*newFrame
= new
212 MyGridBagSizerFrame(_T("wxGridBagSizer Test Frame"), 50, 50);
213 newFrame
->Show(true);
217 // ----------------------------------------------------------------------------
219 // ----------------------------------------------------------------------------
221 void MyFlexSizerFrame::InitFlexSizer(wxFlexGridSizer
*sizer
)
223 for ( int i
= 0; i
< 3; i
++ )
225 for ( int j
= 0; j
< 3; j
++ )
227 sizer
->Add(new wxStaticText
231 wxString::Format(_T("(%d, %d)"), i
+ 1, j
+ 1),
236 0, wxEXPAND
| wxALIGN_CENTER_VERTICAL
| wxALL
, 3);
241 MyFlexSizerFrame::MyFlexSizerFrame(const wxChar
*title
, int x
, int y
)
242 : wxFrame(NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
244 wxFlexGridSizer
*sizerFlex
;
246 // consttuct the first column
247 wxSizer
*sizerCol1
= new wxBoxSizer(wxVERTICAL
);
248 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Ungrowable:")), 0, wxCENTER
| wxTOP
, 20);
249 sizerFlex
= new wxFlexGridSizer(3, 3);
250 InitFlexSizer(sizerFlex
);
251 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
253 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle column:")), 0, wxCENTER
| wxTOP
, 20);
254 sizerFlex
= new wxFlexGridSizer(3, 3);
255 InitFlexSizer(sizerFlex
);
256 sizerFlex
->AddGrowableCol(1);
257 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
259 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle row:")), 0, wxCENTER
| wxTOP
, 20);
260 sizerFlex
= new wxFlexGridSizer(3, 3);
261 InitFlexSizer(sizerFlex
);
262 sizerFlex
->AddGrowableRow(1);
263 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
265 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("All growable columns:")), 0, wxCENTER
| wxTOP
, 20);
266 sizerFlex
= new wxFlexGridSizer(3, 3);
267 InitFlexSizer(sizerFlex
);
268 sizerFlex
->AddGrowableCol(0, 1);
269 sizerFlex
->AddGrowableCol(1, 2);
270 sizerFlex
->AddGrowableCol(2, 3);
271 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
274 wxSizer
*sizerCol2
= new wxBoxSizer(wxVERTICAL
);
275 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle row and column:")), 0, wxCENTER
| wxTOP
, 20);
276 sizerFlex
= new wxFlexGridSizer(3, 3);
277 InitFlexSizer(sizerFlex
);
278 sizerFlex
->AddGrowableCol(1);
279 sizerFlex
->AddGrowableRow(1);
280 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
282 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with horz flex direction")), 0, wxCENTER
| wxTOP
, 20);
283 sizerFlex
= new wxFlexGridSizer(3, 3);
284 InitFlexSizer(sizerFlex
);
285 sizerFlex
->AddGrowableCol(1);
286 sizerFlex
->AddGrowableRow(1);
287 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
288 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
290 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with grow mode == \"none\"")), 0, wxCENTER
| wxTOP
, 20);
291 sizerFlex
= new wxFlexGridSizer(3, 3);
292 InitFlexSizer(sizerFlex
);
293 sizerFlex
->AddGrowableCol(1);
294 sizerFlex
->AddGrowableRow(1);
295 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
296 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_NONE
);
297 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
299 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with grow mode == \"all\"")), 0, wxCENTER
| wxTOP
, 20);
300 sizerFlex
= new wxFlexGridSizer(3, 3);
301 InitFlexSizer(sizerFlex
);
302 sizerFlex
->AddGrowableCol(1);
303 sizerFlex
->AddGrowableRow(1);
304 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
305 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_ALL
);
306 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
308 // add both columns to grid sizer
309 wxGridSizer
*sizerTop
= new wxGridSizer(2, 0, 20);
310 sizerTop
->Add(sizerCol1
, 1, wxEXPAND
);
311 sizerTop
->Add(sizerCol2
, 1, wxEXPAND
);
314 sizerTop
->SetSizeHints(this);
317 // ----------------------------------------------------------------------------
319 // ----------------------------------------------------------------------------
321 MySizerDialog::MySizerDialog(wxWindow
*parent
, const wxChar
*title
)
322 : wxDialog(parent
, wxID_ANY
, wxString(title
))
324 // Begin with first hierarchy: a notebook at the top and
325 // and OK button at the bottom.
327 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
329 wxNotebook
*notebook
= new wxNotebook( this, wxID_ANY
);
330 topsizer
->Add( notebook
, 1, wxGROW
);
332 wxButton
*button
= new wxButton( this, wxID_OK
, _T("OK") );
333 topsizer
->Add( button
, 0, wxALIGN_RIGHT
| wxALL
, 10 );
335 // First page: one big text ctrl
336 wxTextCtrl
*multi
= new wxTextCtrl( notebook
, wxID_ANY
, _T("TextCtrl."), wxDefaultPosition
, wxDefaultSize
, wxTE_MULTILINE
);
337 notebook
->AddPage( multi
, _T("Page One") );
339 // Second page: a text ctrl and a button
340 wxPanel
*panel
= new wxPanel( notebook
, wxID_ANY
);
341 notebook
->AddPage( panel
, _T("Page Two") );
343 wxSizer
*panelsizer
= new wxBoxSizer( wxVERTICAL
);
345 wxTextCtrl
*text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 1."), wxDefaultPosition
, wxSize(250,-1) );
346 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
347 text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 2."), wxDefaultPosition
, wxSize(250,-1) );
348 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
349 wxButton
*button2
= new wxButton( panel
, wxID_ANY
, _T("Hallo") );
350 panelsizer
->Add( button2
, 0, wxALIGN_RIGHT
| wxLEFT
|wxRIGHT
|wxBOTTOM
, 30 );
352 panel
->SetAutoLayout( true );
353 panel
->SetSizer( panelsizer
);
355 // Tell dialog to use sizer
356 SetSizer( topsizer
);
357 topsizer
->SetSizeHints( this );
360 // ----------------------------------------------------------------------------
361 // MyGridBagSizerFrame
362 // ----------------------------------------------------------------------------
364 // some simple macros to help make the sample code below more clear
365 #define TEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text))
366 #define MLTEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE)
367 #define POS(r, c) wxGBPosition(r,c)
368 #define SPAN(r, c) wxGBSpan(r,c)
370 wxChar
* gbsDescription
=_T("\
371 The wxGridBagSizer is similar to the wxFlexGridSizer except the items are explicitly positioned\n\
372 in a virtual cell of the layout grid, and column or row spanning is allowed. For example, this\n\
373 static text is positioned at (0,0) and it spans 7 columns.");
387 BEGIN_EVENT_TABLE(MyGridBagSizerFrame
, wxFrame
)
388 EVT_BUTTON( GBS_HIDE_BTN
, MyGridBagSizerFrame::OnHideBtn
)
389 EVT_BUTTON( GBS_SHOW_BTN
, MyGridBagSizerFrame::OnShowBtn
)
390 EVT_BUTTON( GBS_MOVE_BTN1
, MyGridBagSizerFrame::OnMoveBtn
)
391 EVT_BUTTON( GBS_MOVE_BTN2
, MyGridBagSizerFrame::OnMoveBtn
)
395 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar
*title
, int x
, int y
)
396 : wxFrame( NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
398 wxPanel
* p
= new wxPanel(this, wxID_ANY
);
400 m_gbs
= new wxGridBagSizer();
403 m_gbs
->Add( new wxStaticText(p
, wxID_ANY
, gbsDescription
),
404 POS(0,0), SPAN(1, 7),
405 wxALIGN_CENTER
| wxALL
, 5);
407 m_gbs
->Add( TEXTCTRL("pos(1,0)"), POS(1,0) );
408 m_gbs
->Add( TEXTCTRL("pos(1,1)"), POS(1,1) );
409 m_gbs
->Add( TEXTCTRL("pos(2,0)"), POS(2,0) );
410 m_gbs
->Add( TEXTCTRL("pos(2,1)"), POS(2,1) );
411 m_gbs
->Add( MLTEXTCTRL("pos(3,2), span(1,2)\nthis row and col are growable"),
412 POS(3,2), SPAN(1,2), wxEXPAND
);
413 m_gbs
->Add( MLTEXTCTRL("pos(4,3)\nspan(3,1)"),
414 POS(4,3), SPAN(3,1), wxEXPAND
);
415 m_gbs
->Add( TEXTCTRL("pos(5,4)"), POS(5,4), wxDefaultSpan
, wxEXPAND
);
416 m_gbs
->Add( TEXTCTRL("pos(6,5)"), POS(6,5), wxDefaultSpan
, wxEXPAND
);
417 m_gbs
->Add( TEXTCTRL("pos(7,6)"), POS(7,6) );
419 //m_gbs->Add( TEXTCTRL("bad position"), POS(4,3) ); // Test for assert
420 //m_gbs->Add( TEXTCTRL("bad position"), POS(5,3) ); // Test for assert
423 m_moveBtn1
= new wxButton(p
, GBS_MOVE_BTN1
, _T("Move this to (3,6)"));
424 m_moveBtn2
= new wxButton(p
, GBS_MOVE_BTN2
, _T("Move this to (3,6)"));
425 m_gbs
->Add( m_moveBtn1
, POS(10,2) );
426 m_gbs
->Add( m_moveBtn2
, POS(10,3) );
428 m_hideBtn
= new wxButton(p
, GBS_HIDE_BTN
, _T("Hide this item -->"));
429 m_gbs
->Add(m_hideBtn
, POS(12, 3));
431 m_hideTxt
= new wxTextCtrl(p
, wxID_ANY
, _T("pos(12,4), size(150, -1)"),
432 wxDefaultPosition
, wxSize(150,-1));
433 m_gbs
->Add( m_hideTxt
, POS(12,4) );
435 m_showBtn
= new wxButton(p
, GBS_SHOW_BTN
, _T("<-- Show it again"));
436 m_gbs
->Add(m_showBtn
, POS(12, 5));
437 m_showBtn
->Disable();
439 m_gbs
->Add(10,10, POS(14,0));
441 m_gbs
->AddGrowableRow(3);
442 m_gbs
->AddGrowableCol(2);
444 p
->SetSizerAndFit(m_gbs
);
445 SetClientSize(p
->GetSize());
449 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent
&)
451 m_gbs
->Hide(m_hideTxt
);
452 m_hideBtn
->Disable();
457 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent
&)
459 m_gbs
->Show(m_hideTxt
);
461 m_showBtn
->Disable();
466 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent
& event
)
468 wxButton
* btn
= (wxButton
*)event
.GetEventObject();
469 wxGBPosition curPos
= m_gbs
->GetItemPosition(btn
);
471 // if it's already at the "other" spot then move it back
472 if (curPos
== wxGBPosition(3,6))
474 m_gbs
->SetItemPosition(btn
, m_lastPos
);
475 btn
->SetLabel(_T("Move this to (3,6)"));
479 if ( m_gbs
->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
481 _T("wxGridBagSizer will not allow items to be in the same cell as\n\
482 another item, so this operation will fail. You will also get an assert\n\
483 when compiled in debug mode."), _T("Warning"), wxOK
| wxICON_INFORMATION
);
485 if ( m_gbs
->SetItemPosition(btn
, wxGBPosition(3,6)) )
488 btn
->SetLabel(_T("Move it back"));