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
95 SetStatusText(_T("wxWidgets layout demo"));
98 // we want to get a dialog that is stretchable because it
99 // has a text ctrl in the middle. at the bottom, we have
100 // two buttons which.
102 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
104 // 1) top: create wxStaticText with minimum size equal to its default size
106 new wxStaticText( this, wxID_ANY
, _T("An explanation (wxALIGN_RIGHT).") ),
107 0, // make vertically unstretchable
108 wxALIGN_RIGHT
| // right align text
109 wxTOP
| wxLEFT
| wxRIGHT
, // make border all around except wxBOTTOM
110 5 ); // set border width to 5
112 // 2) top: create wxTextCtrl with minimum size (100x60)
114 new wxTextCtrl( this, wxID_ANY
, _T("My text (wxEXPAND)."), wxDefaultPosition
, wxSize(100,60), wxTE_MULTILINE
),
115 1, // make vertically stretchable
116 wxEXPAND
| // make horizontally stretchable
117 wxALL
, // and make border all around
118 5 ); // set border width to 5
120 // 2.5) Gratuitous test of wxStaticBoxSizers
121 wxBoxSizer
*statsizer
= new wxStaticBoxSizer(
122 new wxStaticBox(this, wxID_ANY
, _T("A wxStaticBoxSizer")),
125 new wxStaticText(this, wxID_ANY
, _T("And some TEXT inside it")),
130 topsizer
->Add(statsizer
, 1, wxEXPAND
| wxALL
, 10);
132 // 2.7) And a test of wxGridSizer
133 wxGridSizer
*gridsizer
= new wxGridSizer(2, 5, 5);
134 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Label")), 0,
135 wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
);
136 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("Grid sizer demo")), 1,
137 wxGROW
| wxALIGN_CENTER_VERTICAL
);
138 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Another label")), 0,
139 wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
);
140 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("More text")), 1,
141 wxGROW
| wxALIGN_CENTER_VERTICAL
);
142 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Final label")), 0,
143 wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
);
144 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("And yet more text")), 1,
145 wxGROW
| wxALIGN_CENTER_VERTICAL
);
146 topsizer
->Add(gridsizer
, 1, wxGROW
| wxALL
, 10);
149 // 3) middle: create wxStaticLine with minimum size (3x3)
151 new wxStaticLine( this, wxID_ANY
, wxDefaultPosition
, wxSize(3,3), wxHORIZONTAL
),
152 0, // make vertically unstretchable
153 wxEXPAND
| // make horizontally stretchable
154 wxALL
, // and make border all around
155 5 ); // set border width to 5
158 // 4) bottom: create two centred wxButtons
159 wxBoxSizer
*button_box
= new wxBoxSizer( wxHORIZONTAL
);
161 new wxButton( this, wxID_ANY
, _T("Two buttons in a box") ),
162 0, // make horizontally unstretchable
163 wxALL
, // make border all around
164 7 ); // set border width to 7
166 new wxButton( this, wxID_ANY
, _T("(wxCENTER)") ),
167 0, // make horizontally unstretchable
168 wxALL
, // make border all around
169 7 ); // set border width to 7
173 0, // make vertically unstretchable
174 wxCENTER
); // no border and centre horizontally
176 // don't allow frame to get smaller than what the sizers tell it and also set
177 // the initial size as calculated by the sizers
178 topsizer
->SetSizeHints( this );
180 SetSizer( topsizer
);
183 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
) )
188 void MyFrame::TestFlexSizers(wxCommandEvent
& WXUNUSED(event
) )
190 MyFlexSizerFrame
*newFrame
= new MyFlexSizerFrame(_T("Flex Sizer Test Frame"), 50, 50);
191 newFrame
->Show(true);
194 void MyFrame::TestNotebookSizers(wxCommandEvent
& WXUNUSED(event
) )
196 MySizerDialog
dialog( this, _T("Notebook Sizer Test Dialog") );
202 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
) )
204 (void)wxMessageBox(_T("wxWidgets GUI library layout demo\n"),
205 _T("About Layout Demo"), wxOK
|wxICON_INFORMATION
);
208 void MyFrame::TestGridBagSizer(wxCommandEvent
& WXUNUSED(event
) )
210 MyGridBagSizerFrame
*newFrame
= new
211 MyGridBagSizerFrame(_T("wxGridBagSizer Test Frame"), 50, 50);
212 newFrame
->Show(true);
216 // ----------------------------------------------------------------------------
218 // ----------------------------------------------------------------------------
220 void MyFlexSizerFrame::InitFlexSizer(wxFlexGridSizer
*sizer
)
222 for ( int i
= 0; i
< 3; i
++ )
224 for ( int j
= 0; j
< 3; j
++ )
226 sizer
->Add(new wxStaticText
230 wxString::Format(_T("(%d, %d)"), i
+ 1, j
+ 1),
235 0, wxEXPAND
| wxALIGN_CENTER_VERTICAL
| wxALL
, 3);
240 MyFlexSizerFrame::MyFlexSizerFrame(const wxChar
*title
, int x
, int y
)
241 : wxFrame(NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
243 wxFlexGridSizer
*sizerFlex
;
245 // consttuct the first column
246 wxSizer
*sizerCol1
= new wxBoxSizer(wxVERTICAL
);
247 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Ungrowable:")), 0, wxCENTER
| wxTOP
, 20);
248 sizerFlex
= new wxFlexGridSizer(3, 3);
249 InitFlexSizer(sizerFlex
);
250 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
252 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle column:")), 0, wxCENTER
| wxTOP
, 20);
253 sizerFlex
= new wxFlexGridSizer(3, 3);
254 InitFlexSizer(sizerFlex
);
255 sizerFlex
->AddGrowableCol(1);
256 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
258 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle row:")), 0, wxCENTER
| wxTOP
, 20);
259 sizerFlex
= new wxFlexGridSizer(3, 3);
260 InitFlexSizer(sizerFlex
);
261 sizerFlex
->AddGrowableRow(1);
262 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
264 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("All growable columns:")), 0, wxCENTER
| wxTOP
, 20);
265 sizerFlex
= new wxFlexGridSizer(3, 3);
266 InitFlexSizer(sizerFlex
);
267 sizerFlex
->AddGrowableCol(0, 1);
268 sizerFlex
->AddGrowableCol(1, 2);
269 sizerFlex
->AddGrowableCol(2, 3);
270 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
273 wxSizer
*sizerCol2
= new wxBoxSizer(wxVERTICAL
);
274 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle row and column:")), 0, wxCENTER
| wxTOP
, 20);
275 sizerFlex
= new wxFlexGridSizer(3, 3);
276 InitFlexSizer(sizerFlex
);
277 sizerFlex
->AddGrowableCol(1);
278 sizerFlex
->AddGrowableRow(1);
279 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
281 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with horz flex direction")), 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 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
289 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with grow mode == \"none\"")), 0, wxCENTER
| wxTOP
, 20);
290 sizerFlex
= new wxFlexGridSizer(3, 3);
291 InitFlexSizer(sizerFlex
);
292 sizerFlex
->AddGrowableCol(1);
293 sizerFlex
->AddGrowableRow(1);
294 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
295 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_NONE
);
296 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
298 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with grow mode == \"all\"")), 0, wxCENTER
| wxTOP
, 20);
299 sizerFlex
= new wxFlexGridSizer(3, 3);
300 InitFlexSizer(sizerFlex
);
301 sizerFlex
->AddGrowableCol(1);
302 sizerFlex
->AddGrowableRow(1);
303 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
304 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_ALL
);
305 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
307 // add both columns to grid sizer
308 wxGridSizer
*sizerTop
= new wxGridSizer(2, 0, 20);
309 sizerTop
->Add(sizerCol1
, 1, wxEXPAND
);
310 sizerTop
->Add(sizerCol2
, 1, wxEXPAND
);
313 sizerTop
->SetSizeHints(this);
316 // ----------------------------------------------------------------------------
318 // ----------------------------------------------------------------------------
320 MySizerDialog::MySizerDialog(wxWindow
*parent
, const wxChar
*title
)
321 : wxDialog(parent
, wxID_ANY
, wxString(title
))
323 // Begin with first hierarchy: a notebook at the top and
324 // and OK button at the bottom.
326 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
328 wxNotebook
*notebook
= new wxNotebook( this, wxID_ANY
);
329 topsizer
->Add( notebook
, 1, wxGROW
);
331 wxButton
*button
= new wxButton( this, wxID_OK
, _T("OK") );
332 topsizer
->Add( button
, 0, wxALIGN_RIGHT
| wxALL
, 10 );
334 // First page: one big text ctrl
335 wxTextCtrl
*multi
= new wxTextCtrl( notebook
, wxID_ANY
, _T("TextCtrl."), wxDefaultPosition
, wxDefaultSize
, wxTE_MULTILINE
);
336 notebook
->AddPage( multi
, _T("Page One") );
338 // Second page: a text ctrl and a button
339 wxPanel
*panel
= new wxPanel( notebook
, wxID_ANY
);
340 notebook
->AddPage( panel
, _T("Page Two") );
342 wxSizer
*panelsizer
= new wxBoxSizer( wxVERTICAL
);
344 wxTextCtrl
*text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 1."), wxDefaultPosition
, wxSize(250,-1) );
345 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
346 text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 2."), wxDefaultPosition
, wxSize(250,-1) );
347 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
348 wxButton
*button2
= new wxButton( panel
, wxID_ANY
, _T("Hallo") );
349 panelsizer
->Add( button2
, 0, wxALIGN_RIGHT
| wxLEFT
|wxRIGHT
|wxBOTTOM
, 30 );
351 panel
->SetAutoLayout( true );
352 panel
->SetSizer( panelsizer
);
354 // Tell dialog to use sizer
355 SetSizer( topsizer
);
356 topsizer
->SetSizeHints( this );
359 // ----------------------------------------------------------------------------
360 // MyGridBagSizerFrame
361 // ----------------------------------------------------------------------------
363 // some simple macros to help make the sample code below more clear
364 #define TEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text))
365 #define MLTEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE)
366 #define POS(r, c) wxGBPosition(r,c)
367 #define SPAN(r, c) wxGBSpan(r,c)
369 wxChar
* gbsDescription
=_T("\
370 The wxGridBagSizer is similar to the wxFlexGridSizer except the items are explicitly positioned\n\
371 in a virtual cell of the layout grid, and column or row spanning is allowed. For example, this\n\
372 static text is positioned at (0,0) and it spans 7 columns.");
386 BEGIN_EVENT_TABLE(MyGridBagSizerFrame
, wxFrame
)
387 EVT_BUTTON( GBS_HIDE_BTN
, MyGridBagSizerFrame::OnHideBtn
)
388 EVT_BUTTON( GBS_SHOW_BTN
, MyGridBagSizerFrame::OnShowBtn
)
389 EVT_BUTTON( GBS_MOVE_BTN1
, MyGridBagSizerFrame::OnMoveBtn
)
390 EVT_BUTTON( GBS_MOVE_BTN2
, MyGridBagSizerFrame::OnMoveBtn
)
394 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar
*title
, int x
, int y
)
395 : wxFrame( NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
397 wxPanel
* p
= new wxPanel(this, wxID_ANY
);
399 m_gbs
= new wxGridBagSizer();
402 m_gbs
->Add( new wxStaticText(p
, wxID_ANY
, gbsDescription
),
403 POS(0,0), SPAN(1, 7),
404 wxALIGN_CENTER
| wxALL
, 5);
406 m_gbs
->Add( TEXTCTRL("pos(1,0)"), POS(1,0) );
407 m_gbs
->Add( TEXTCTRL("pos(1,1)"), POS(1,1) );
408 m_gbs
->Add( TEXTCTRL("pos(2,0)"), POS(2,0) );
409 m_gbs
->Add( TEXTCTRL("pos(2,1)"), POS(2,1) );
410 m_gbs
->Add( MLTEXTCTRL("pos(3,2), span(1,2)\nthis row and col are growable"),
411 POS(3,2), SPAN(1,2), wxEXPAND
);
412 m_gbs
->Add( MLTEXTCTRL("pos(4,3)\nspan(3,1)"),
413 POS(4,3), SPAN(3,1), wxEXPAND
);
414 m_gbs
->Add( TEXTCTRL("pos(5,4)"), POS(5,4), wxDefaultSpan
, wxEXPAND
);
415 m_gbs
->Add( TEXTCTRL("pos(6,5)"), POS(6,5), wxDefaultSpan
, wxEXPAND
);
416 m_gbs
->Add( TEXTCTRL("pos(7,6)"), POS(7,6) );
418 //m_gbs->Add( TEXTCTRL("bad position"), POS(4,3) ); // Test for assert
419 //m_gbs->Add( TEXTCTRL("bad position"), POS(5,3) ); // Test for assert
422 m_moveBtn1
= new wxButton(p
, GBS_MOVE_BTN1
, _T("Move this to (3,6)"));
423 m_moveBtn2
= new wxButton(p
, GBS_MOVE_BTN2
, _T("Move this to (3,6)"));
424 m_gbs
->Add( m_moveBtn1
, POS(10,2) );
425 m_gbs
->Add( m_moveBtn2
, POS(10,3) );
427 m_hideBtn
= new wxButton(p
, GBS_HIDE_BTN
, _T("Hide this item -->"));
428 m_gbs
->Add(m_hideBtn
, POS(12, 3));
430 m_hideTxt
= new wxTextCtrl(p
, wxID_ANY
, _T("pos(12,4), size(150, -1)"),
431 wxDefaultPosition
, wxSize(150,-1));
432 m_gbs
->Add( m_hideTxt
, POS(12,4) );
434 m_showBtn
= new wxButton(p
, GBS_SHOW_BTN
, _T("<-- Show it again"));
435 m_gbs
->Add(m_showBtn
, POS(12, 5));
436 m_showBtn
->Disable();
438 m_gbs
->Add(10,10, POS(14,0));
440 m_gbs
->AddGrowableRow(3);
441 m_gbs
->AddGrowableCol(2);
443 p
->SetSizerAndFit(m_gbs
);
444 SetClientSize(p
->GetSize());
448 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent
&)
450 m_gbs
->Hide(m_hideTxt
);
451 m_hideBtn
->Disable();
456 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent
&)
458 m_gbs
->Show(m_hideTxt
);
460 m_showBtn
->Disable();
465 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent
& event
)
467 wxButton
* btn
= (wxButton
*)event
.GetEventObject();
468 wxGBPosition curPos
= m_gbs
->GetItemPosition(btn
);
470 // if it's already at the "other" spot then move it back
471 if (curPos
== wxGBPosition(3,6))
473 m_gbs
->SetItemPosition(btn
, m_lastPos
);
474 btn
->SetLabel(_T("Move this to (3,6)"));
478 if ( m_gbs
->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
480 _T("wxGridBagSizer will not allow items to be in the same cell as\n\
481 another item, so this operation will fail. You will also get an assert\n\
482 when compiled in debug mode."), _T("Warning"), wxOK
| wxICON_INFORMATION
);
484 if ( m_gbs
->SetItemPosition(btn
, wxGBPosition(3,6)) )
487 btn
->SetLabel(_T("Move it back"));