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("wxWindows 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("wxWindows 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("wxWindows 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 wxNotebookSizer
*nbs
= new wxNotebookSizer( notebook
);
330 topsizer
->Add( nbs
, 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"));