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 wxPanel
* p
= new wxPanel(this, -1);
97 // we want to get a dialog that is stretchable because it
98 // has a text ctrl in the middle. at the bottom, we have
101 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
103 // 1) top: create wxStaticText with minimum size equal to its default size
105 new wxStaticText( p
, wxID_ANY
, _T("An explanation (wxALIGN_RIGHT).") ),
106 wxSizerFlags().Align(wxALIGN_RIGHT
).Border(wxALL
& ~wxBOTTOM
, 5));
108 // 2) top: create wxTextCtrl with minimum size (100x60)
110 new wxTextCtrl( p
, wxID_ANY
, _T("My text (wxEXPAND)."), wxDefaultPosition
, wxSize(100,60), wxTE_MULTILINE
),
111 wxSizerFlags(1).Expand().Border(wxALL
, 5));
113 // 2.5) Gratuitous test of wxStaticBoxSizers
114 wxBoxSizer
*statsizer
= new wxStaticBoxSizer(
115 new wxStaticBox(p
, wxID_ANY
, _T("A wxStaticBoxSizer")), wxVERTICAL
);
117 new wxStaticText(p
, wxID_ANY
, _T("And some TEXT inside it")),
118 wxSizerFlags().Center().Border(wxALL
, 30));
121 wxSizerFlags(1).Expand().Border(wxALL
, 10));
123 // 2.7) And a test of wxGridSizer
124 wxGridSizer
*gridsizer
= new wxGridSizer(2, 5, 5);
125 gridsizer
->Add(new wxStaticText(p
, wxID_ANY
, _T("Label")),
126 wxSizerFlags().Align(wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
));
127 gridsizer
->Add(new wxTextCtrl(p
, wxID_ANY
, _T("Grid sizer demo")),
128 wxSizerFlags(1).Align(wxGROW
| wxALIGN_CENTER_VERTICAL
));
129 gridsizer
->Add(new wxStaticText(p
, wxID_ANY
, _T("Another label")),
130 wxSizerFlags().Align(wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
));
131 gridsizer
->Add(new wxTextCtrl(p
, wxID_ANY
, _T("More text")),
132 wxSizerFlags(1).Align(wxGROW
| wxALIGN_CENTER_VERTICAL
));
133 gridsizer
->Add(new wxStaticText(p
, wxID_ANY
, _T("Final label")),
134 wxSizerFlags().Align(wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
));
135 gridsizer
->Add(new wxTextCtrl(p
, wxID_ANY
, _T("And yet more text")),
136 wxSizerFlags().Align(wxGROW
| wxALIGN_CENTER_VERTICAL
));
139 wxSizerFlags().Proportion(1).Expand().Border(wxALL
, 10));
143 // 3) middle: create wxStaticLine with minimum size (3x3)
145 new wxStaticLine( p
, wxID_ANY
, wxDefaultPosition
, wxSize(3,3), wxHORIZONTAL
),
146 wxSizerFlags().Expand());
147 #endif // wxUSE_STATLINE
150 // 4) bottom: create two centred wxButtons
151 wxBoxSizer
*button_box
= new wxBoxSizer( wxHORIZONTAL
);
153 new wxButton( p
, wxID_ANY
, _T("Two buttons in a box") ),
154 wxSizerFlags().Border(wxALL
, 7));
156 new wxButton( p
, wxID_ANY
, _T("(wxCENTER)") ),
157 wxSizerFlags().Border(wxALL
, 7));
159 topsizer
->Add(button_box
, wxSizerFlags().Center());
161 p
->SetSizer( topsizer
);
163 // don't allow frame to get smaller than what the sizers tell it and also set
164 // the initial size as calculated by the sizers
165 topsizer
->SetSizeHints( this );
168 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
) )
173 void MyFrame::TestFlexSizers(wxCommandEvent
& WXUNUSED(event
) )
175 MyFlexSizerFrame
*newFrame
= new MyFlexSizerFrame(_T("Flex Sizer Test Frame"), 50, 50);
176 newFrame
->Show(true);
179 void MyFrame::TestNotebookSizers(wxCommandEvent
& WXUNUSED(event
) )
181 MySizerDialog
dialog( this, _T("Notebook Sizer Test Dialog") );
187 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
) )
189 (void)wxMessageBox(_T("wxWidgets GUI library layout demo\n"),
190 _T("About Layout Demo"), wxOK
|wxICON_INFORMATION
);
193 void MyFrame::TestGridBagSizer(wxCommandEvent
& WXUNUSED(event
) )
195 MyGridBagSizerFrame
*newFrame
= new
196 MyGridBagSizerFrame(_T("wxGridBagSizer Test Frame"), 50, 50);
197 newFrame
->Show(true);
201 // ----------------------------------------------------------------------------
203 // ----------------------------------------------------------------------------
205 void MyFlexSizerFrame::InitFlexSizer(wxFlexGridSizer
*sizer
, wxWindow
* parent
)
207 for ( int i
= 0; i
< 3; i
++ )
209 for ( int j
= 0; j
< 3; j
++ )
211 sizer
->Add(new wxStaticText
215 wxString::Format(_T("(%d, %d)"), i
+ 1, j
+ 1),
220 0, wxEXPAND
| wxALIGN_CENTER_VERTICAL
| wxALL
, 3);
225 MyFlexSizerFrame::MyFlexSizerFrame(const wxChar
*title
, int x
, int y
)
226 : wxFrame(NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
228 wxFlexGridSizer
*sizerFlex
;
229 wxPanel
* p
= new wxPanel(this, -1);
231 // consttuct the first column
232 wxSizer
*sizerCol1
= new wxBoxSizer(wxVERTICAL
);
233 sizerCol1
->Add(new wxStaticText(p
, wxID_ANY
, _T("Ungrowable:")), 0, wxCENTER
| wxTOP
, 20);
234 sizerFlex
= new wxFlexGridSizer(3, 3);
235 InitFlexSizer(sizerFlex
, p
);
236 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
238 sizerCol1
->Add(new wxStaticText(p
, wxID_ANY
, _T("Growable middle column:")), 0, wxCENTER
| wxTOP
, 20);
239 sizerFlex
= new wxFlexGridSizer(3, 3);
240 InitFlexSizer(sizerFlex
, p
);
241 sizerFlex
->AddGrowableCol(1);
242 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
244 sizerCol1
->Add(new wxStaticText(p
, wxID_ANY
, _T("Growable middle row:")), 0, wxCENTER
| wxTOP
, 20);
245 sizerFlex
= new wxFlexGridSizer(3, 3);
246 InitFlexSizer(sizerFlex
, p
);
247 sizerFlex
->AddGrowableRow(1);
248 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
250 sizerCol1
->Add(new wxStaticText(p
, wxID_ANY
, _T("All growable columns:")), 0, wxCENTER
| wxTOP
, 20);
251 sizerFlex
= new wxFlexGridSizer(3, 3);
252 InitFlexSizer(sizerFlex
, p
);
253 sizerFlex
->AddGrowableCol(0, 1);
254 sizerFlex
->AddGrowableCol(1, 2);
255 sizerFlex
->AddGrowableCol(2, 3);
256 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
259 wxSizer
*sizerCol2
= new wxBoxSizer(wxVERTICAL
);
260 sizerCol2
->Add(new wxStaticText(p
, wxID_ANY
, _T("Growable middle row and column:")), 0, wxCENTER
| wxTOP
, 20);
261 sizerFlex
= new wxFlexGridSizer(3, 3);
262 InitFlexSizer(sizerFlex
, p
);
263 sizerFlex
->AddGrowableCol(1);
264 sizerFlex
->AddGrowableRow(1);
265 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
267 sizerCol2
->Add(new wxStaticText(p
, wxID_ANY
, _T("Same with horz flex direction")), 0, wxCENTER
| wxTOP
, 20);
268 sizerFlex
= new wxFlexGridSizer(3, 3);
269 InitFlexSizer(sizerFlex
, p
);
270 sizerFlex
->AddGrowableCol(1);
271 sizerFlex
->AddGrowableRow(1);
272 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
273 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
275 sizerCol2
->Add(new wxStaticText(p
, wxID_ANY
, _T("Same with grow mode == \"none\"")), 0, wxCENTER
| wxTOP
, 20);
276 sizerFlex
= new wxFlexGridSizer(3, 3);
277 InitFlexSizer(sizerFlex
, p
);
278 sizerFlex
->AddGrowableCol(1);
279 sizerFlex
->AddGrowableRow(1);
280 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
281 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_NONE
);
282 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
284 sizerCol2
->Add(new wxStaticText(p
, wxID_ANY
, _T("Same with grow mode == \"all\"")), 0, wxCENTER
| wxTOP
, 20);
285 sizerFlex
= new wxFlexGridSizer(3, 3);
286 InitFlexSizer(sizerFlex
, p
);
287 sizerFlex
->AddGrowableCol(1);
288 sizerFlex
->AddGrowableRow(1);
289 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
290 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_ALL
);
291 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
293 // add both columns to grid sizer
294 wxGridSizer
*sizerTop
= new wxGridSizer(2, 0, 20);
295 sizerTop
->Add(sizerCol1
, 1, wxEXPAND
);
296 sizerTop
->Add(sizerCol2
, 1, wxEXPAND
);
298 p
->SetSizer(sizerTop
);
299 sizerTop
->SetSizeHints(this);
302 // ----------------------------------------------------------------------------
304 // ----------------------------------------------------------------------------
306 MySizerDialog::MySizerDialog(wxWindow
*parent
, const wxChar
*title
)
307 : wxDialog(parent
, wxID_ANY
, wxString(title
))
309 // Begin with first hierarchy: a notebook at the top and
310 // and OK button at the bottom.
312 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
314 wxNotebook
*notebook
= new wxNotebook( this, wxID_ANY
);
315 topsizer
->Add( notebook
, 1, wxGROW
);
317 wxButton
*button
= new wxButton( this, wxID_OK
, _T("OK") );
318 topsizer
->Add( button
, 0, wxALIGN_RIGHT
| wxALL
, 10 );
320 // First page: one big text ctrl
321 wxTextCtrl
*multi
= new wxTextCtrl( notebook
, wxID_ANY
, _T("TextCtrl."), wxDefaultPosition
, wxDefaultSize
, wxTE_MULTILINE
);
322 notebook
->AddPage( multi
, _T("Page One") );
324 // Second page: a text ctrl and a button
325 wxPanel
*panel
= new wxPanel( notebook
, wxID_ANY
);
326 notebook
->AddPage( panel
, _T("Page Two") );
328 wxSizer
*panelsizer
= new wxBoxSizer( wxVERTICAL
);
330 wxTextCtrl
*text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 1."), wxDefaultPosition
, wxSize(250,-1) );
331 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
332 text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 2."), wxDefaultPosition
, wxSize(250,-1) );
333 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
334 wxButton
*button2
= new wxButton( panel
, wxID_ANY
, _T("Hallo") );
335 panelsizer
->Add( button2
, 0, wxALIGN_RIGHT
| wxLEFT
|wxRIGHT
|wxBOTTOM
, 30 );
337 panel
->SetAutoLayout( true );
338 panel
->SetSizer( panelsizer
);
340 // Tell dialog to use sizer
341 SetSizer( topsizer
);
342 topsizer
->SetSizeHints( this );
345 // ----------------------------------------------------------------------------
346 // MyGridBagSizerFrame
347 // ----------------------------------------------------------------------------
349 // some simple macros to help make the sample code below more clear
350 #define TEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text))
351 #define MLTEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE)
352 #define POS(r, c) wxGBPosition(r,c)
353 #define SPAN(r, c) wxGBSpan(r,c)
355 wxChar
* gbsDescription
=_T("\
356 The wxGridBagSizer is similar to the wxFlexGridSizer except the items are explicitly positioned\n\
357 in a virtual cell of the layout grid, and column or row spanning is allowed. For example, this\n\
358 static text is positioned at (0,0) and it spans 7 columns.");
372 BEGIN_EVENT_TABLE(MyGridBagSizerFrame
, wxFrame
)
373 EVT_BUTTON( GBS_HIDE_BTN
, MyGridBagSizerFrame::OnHideBtn
)
374 EVT_BUTTON( GBS_SHOW_BTN
, MyGridBagSizerFrame::OnShowBtn
)
375 EVT_BUTTON( GBS_MOVE_BTN1
, MyGridBagSizerFrame::OnMoveBtn
)
376 EVT_BUTTON( GBS_MOVE_BTN2
, MyGridBagSizerFrame::OnMoveBtn
)
380 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar
*title
, int x
, int y
)
381 : wxFrame( NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
383 wxPanel
* p
= new wxPanel(this, wxID_ANY
);
385 m_gbs
= new wxGridBagSizer();
388 m_gbs
->Add( new wxStaticText(p
, wxID_ANY
, gbsDescription
),
389 POS(0,0), SPAN(1, 7),
390 wxALIGN_CENTER
| wxALL
, 5);
392 m_gbs
->Add( TEXTCTRL("pos(1,0)"), POS(1,0) );
393 m_gbs
->Add( TEXTCTRL("pos(1,1)"), POS(1,1) );
394 m_gbs
->Add( TEXTCTRL("pos(2,0)"), POS(2,0) );
395 m_gbs
->Add( TEXTCTRL("pos(2,1)"), POS(2,1) );
396 m_gbs
->Add( MLTEXTCTRL("pos(3,2), span(1,2)\nthis row and col are growable"),
397 POS(3,2), SPAN(1,2), wxEXPAND
);
398 m_gbs
->Add( MLTEXTCTRL("pos(4,3)\nspan(3,1)"),
399 POS(4,3), SPAN(3,1), wxEXPAND
);
400 m_gbs
->Add( TEXTCTRL("pos(5,4)"), POS(5,4), wxDefaultSpan
, wxEXPAND
);
401 m_gbs
->Add( TEXTCTRL("pos(6,5)"), POS(6,5), wxDefaultSpan
, wxEXPAND
);
402 m_gbs
->Add( TEXTCTRL("pos(7,6)"), POS(7,6) );
404 //m_gbs->Add( TEXTCTRL("bad position"), POS(4,3) ); // Test for assert
405 //m_gbs->Add( TEXTCTRL("bad position"), POS(5,3) ); // Test for assert
408 m_moveBtn1
= new wxButton(p
, GBS_MOVE_BTN1
, _T("Move this to (3,6)"));
409 m_moveBtn2
= new wxButton(p
, GBS_MOVE_BTN2
, _T("Move this to (3,6)"));
410 m_gbs
->Add( m_moveBtn1
, POS(10,2) );
411 m_gbs
->Add( m_moveBtn2
, POS(10,3) );
413 m_hideBtn
= new wxButton(p
, GBS_HIDE_BTN
, _T("Hide this item -->"));
414 m_gbs
->Add(m_hideBtn
, POS(12, 3));
416 m_hideTxt
= new wxTextCtrl(p
, wxID_ANY
, _T("pos(12,4), size(150, -1)"),
417 wxDefaultPosition
, wxSize(150,-1));
418 m_gbs
->Add( m_hideTxt
, POS(12,4) );
420 m_showBtn
= new wxButton(p
, GBS_SHOW_BTN
, _T("<-- Show it again"));
421 m_gbs
->Add(m_showBtn
, POS(12, 5));
422 m_showBtn
->Disable();
424 m_gbs
->Add(10,10, POS(14,0));
426 m_gbs
->AddGrowableRow(3);
427 m_gbs
->AddGrowableCol(2);
429 p
->SetSizerAndFit(m_gbs
);
430 SetClientSize(p
->GetSize());
434 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent
&)
436 m_gbs
->Hide(m_hideTxt
);
437 m_hideBtn
->Disable();
442 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent
&)
444 m_gbs
->Show(m_hideTxt
);
446 m_showBtn
->Disable();
451 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent
& event
)
453 wxButton
* btn
= (wxButton
*)event
.GetEventObject();
454 wxGBPosition curPos
= m_gbs
->GetItemPosition(btn
);
456 // if it's already at the "other" spot then move it back
457 if (curPos
== wxGBPosition(3,6))
459 m_gbs
->SetItemPosition(btn
, m_lastPos
);
460 btn
->SetLabel(_T("Move this to (3,6)"));
464 if ( m_gbs
->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
466 _T("wxGridBagSizer will not allow items to be in the same cell as\n\
467 another item, so this operation will fail. You will also get an assert\n\
468 when compiled in debug mode."), _T("Warning"), wxOK
| wxICON_INFORMATION
);
470 if ( m_gbs
->SetItemPosition(btn
, wxGBPosition(3,6)) )
473 btn
->SetLabel(_T("Move it back"));