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 wxSizerFlags().Align(wxALIGN_RIGHT
).Border(wxALL
& ~wxBOTTOM
, 5));
110 // 2) top: create wxTextCtrl with minimum size (100x60)
112 new wxTextCtrl( this, wxID_ANY
, _T("My text (wxEXPAND)."), wxDefaultPosition
, wxSize(100,60), wxTE_MULTILINE
),
113 wxSizerFlags(1).Expand().Border(wxALL
, 5));
115 // 2.5) Gratuitous test of wxStaticBoxSizers
116 wxBoxSizer
*statsizer
= new wxStaticBoxSizer(
117 new wxStaticBox(this, wxID_ANY
, _T("A wxStaticBoxSizer")), wxVERTICAL
);
119 new wxStaticText(this, wxID_ANY
, _T("And some TEXT inside it")),
120 wxSizerFlags().Center().Border(wxALL
, 30));
123 wxSizerFlags(1).Expand().Border(wxALL
, 10));
125 // 2.7) And a test of wxGridSizer
126 wxGridSizer
*gridsizer
= new wxGridSizer(2, 5, 5);
127 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Label")),
128 wxSizerFlags().Align(wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
));
129 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("Grid sizer demo")),
130 wxSizerFlags(1).Align(wxGROW
| wxALIGN_CENTER_VERTICAL
));
131 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Another label")),
132 wxSizerFlags().Align(wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
));
133 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("More text")),
134 wxSizerFlags(1).Align(wxGROW
| wxALIGN_CENTER_VERTICAL
));
135 gridsizer
->Add(new wxStaticText(this, wxID_ANY
, _T("Final label")),
136 wxSizerFlags().Align(wxALIGN_RIGHT
| wxALIGN_CENTER_VERTICAL
));
137 gridsizer
->Add(new wxTextCtrl(this, wxID_ANY
, _T("And yet more text")),
138 wxSizerFlags().Align(wxGROW
| wxALIGN_CENTER_VERTICAL
));
141 wxSizerFlags().Proportion(1).Expand().Border(wxALL
, 10));
145 // 3) middle: create wxStaticLine with minimum size (3x3)
147 new wxStaticLine( this, wxID_ANY
, wxDefaultPosition
, wxSize(3,3), wxHORIZONTAL
),
148 wxSizerFlags().Expand());
149 #endif // wxUSE_STATLINE
152 // 4) bottom: create two centred wxButtons
153 wxBoxSizer
*button_box
= new wxBoxSizer( wxHORIZONTAL
);
155 new wxButton( this, wxID_ANY
, _T("Two buttons in a box") ),
156 wxSizerFlags().Border(wxALL
, 7));
158 new wxButton( this, wxID_ANY
, _T("(wxCENTER)") ),
159 wxSizerFlags().Border(wxALL
, 7));
161 topsizer
->Add(button_box
, wxSizerFlags().Center());
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 );
167 SetSizer( topsizer
);
170 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
) )
175 void MyFrame::TestFlexSizers(wxCommandEvent
& WXUNUSED(event
) )
177 MyFlexSizerFrame
*newFrame
= new MyFlexSizerFrame(_T("Flex Sizer Test Frame"), 50, 50);
178 newFrame
->Show(true);
181 void MyFrame::TestNotebookSizers(wxCommandEvent
& WXUNUSED(event
) )
183 MySizerDialog
dialog( this, _T("Notebook Sizer Test Dialog") );
189 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
) )
191 (void)wxMessageBox(_T("wxWidgets GUI library layout demo\n"),
192 _T("About Layout Demo"), wxOK
|wxICON_INFORMATION
);
195 void MyFrame::TestGridBagSizer(wxCommandEvent
& WXUNUSED(event
) )
197 MyGridBagSizerFrame
*newFrame
= new
198 MyGridBagSizerFrame(_T("wxGridBagSizer Test Frame"), 50, 50);
199 newFrame
->Show(true);
203 // ----------------------------------------------------------------------------
205 // ----------------------------------------------------------------------------
207 void MyFlexSizerFrame::InitFlexSizer(wxFlexGridSizer
*sizer
)
209 for ( int i
= 0; i
< 3; i
++ )
211 for ( int j
= 0; j
< 3; j
++ )
213 sizer
->Add(new wxStaticText
217 wxString::Format(_T("(%d, %d)"), i
+ 1, j
+ 1),
222 0, wxEXPAND
| wxALIGN_CENTER_VERTICAL
| wxALL
, 3);
227 MyFlexSizerFrame::MyFlexSizerFrame(const wxChar
*title
, int x
, int y
)
228 : wxFrame(NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
230 wxFlexGridSizer
*sizerFlex
;
232 // consttuct the first column
233 wxSizer
*sizerCol1
= new wxBoxSizer(wxVERTICAL
);
234 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Ungrowable:")), 0, wxCENTER
| wxTOP
, 20);
235 sizerFlex
= new wxFlexGridSizer(3, 3);
236 InitFlexSizer(sizerFlex
);
237 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
239 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle column:")), 0, wxCENTER
| wxTOP
, 20);
240 sizerFlex
= new wxFlexGridSizer(3, 3);
241 InitFlexSizer(sizerFlex
);
242 sizerFlex
->AddGrowableCol(1);
243 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
245 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle row:")), 0, wxCENTER
| wxTOP
, 20);
246 sizerFlex
= new wxFlexGridSizer(3, 3);
247 InitFlexSizer(sizerFlex
);
248 sizerFlex
->AddGrowableRow(1);
249 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
251 sizerCol1
->Add(new wxStaticText(this, wxID_ANY
, _T("All growable columns:")), 0, wxCENTER
| wxTOP
, 20);
252 sizerFlex
= new wxFlexGridSizer(3, 3);
253 InitFlexSizer(sizerFlex
);
254 sizerFlex
->AddGrowableCol(0, 1);
255 sizerFlex
->AddGrowableCol(1, 2);
256 sizerFlex
->AddGrowableCol(2, 3);
257 sizerCol1
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
260 wxSizer
*sizerCol2
= new wxBoxSizer(wxVERTICAL
);
261 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Growable middle row and column:")), 0, wxCENTER
| wxTOP
, 20);
262 sizerFlex
= new wxFlexGridSizer(3, 3);
263 InitFlexSizer(sizerFlex
);
264 sizerFlex
->AddGrowableCol(1);
265 sizerFlex
->AddGrowableRow(1);
266 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
268 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with horz flex direction")), 0, wxCENTER
| wxTOP
, 20);
269 sizerFlex
= new wxFlexGridSizer(3, 3);
270 InitFlexSizer(sizerFlex
);
271 sizerFlex
->AddGrowableCol(1);
272 sizerFlex
->AddGrowableRow(1);
273 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
274 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
276 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with grow mode == \"none\"")), 0, wxCENTER
| wxTOP
, 20);
277 sizerFlex
= new wxFlexGridSizer(3, 3);
278 InitFlexSizer(sizerFlex
);
279 sizerFlex
->AddGrowableCol(1);
280 sizerFlex
->AddGrowableRow(1);
281 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
282 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_NONE
);
283 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
285 sizerCol2
->Add(new wxStaticText(this, wxID_ANY
, _T("Same with grow mode == \"all\"")), 0, wxCENTER
| wxTOP
, 20);
286 sizerFlex
= new wxFlexGridSizer(3, 3);
287 InitFlexSizer(sizerFlex
);
288 sizerFlex
->AddGrowableCol(1);
289 sizerFlex
->AddGrowableRow(1);
290 sizerFlex
->SetFlexibleDirection(wxHORIZONTAL
);
291 sizerFlex
->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_ALL
);
292 sizerCol2
->Add(sizerFlex
, 1, wxALL
| wxEXPAND
, 10);
294 // add both columns to grid sizer
295 wxGridSizer
*sizerTop
= new wxGridSizer(2, 0, 20);
296 sizerTop
->Add(sizerCol1
, 1, wxEXPAND
);
297 sizerTop
->Add(sizerCol2
, 1, wxEXPAND
);
300 sizerTop
->SetSizeHints(this);
303 // ----------------------------------------------------------------------------
305 // ----------------------------------------------------------------------------
307 MySizerDialog::MySizerDialog(wxWindow
*parent
, const wxChar
*title
)
308 : wxDialog(parent
, wxID_ANY
, wxString(title
))
310 // Begin with first hierarchy: a notebook at the top and
311 // and OK button at the bottom.
313 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
315 wxNotebook
*notebook
= new wxNotebook( this, wxID_ANY
);
316 topsizer
->Add( notebook
, 1, wxGROW
);
318 wxButton
*button
= new wxButton( this, wxID_OK
, _T("OK") );
319 topsizer
->Add( button
, 0, wxALIGN_RIGHT
| wxALL
, 10 );
321 // First page: one big text ctrl
322 wxTextCtrl
*multi
= new wxTextCtrl( notebook
, wxID_ANY
, _T("TextCtrl."), wxDefaultPosition
, wxDefaultSize
, wxTE_MULTILINE
);
323 notebook
->AddPage( multi
, _T("Page One") );
325 // Second page: a text ctrl and a button
326 wxPanel
*panel
= new wxPanel( notebook
, wxID_ANY
);
327 notebook
->AddPage( panel
, _T("Page Two") );
329 wxSizer
*panelsizer
= new wxBoxSizer( wxVERTICAL
);
331 wxTextCtrl
*text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 1."), wxDefaultPosition
, wxSize(250,-1) );
332 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
333 text
= new wxTextCtrl( panel
, wxID_ANY
, _T("TextLine 2."), wxDefaultPosition
, wxSize(250,-1) );
334 panelsizer
->Add( text
, 0, wxGROW
|wxALL
, 30 );
335 wxButton
*button2
= new wxButton( panel
, wxID_ANY
, _T("Hallo") );
336 panelsizer
->Add( button2
, 0, wxALIGN_RIGHT
| wxLEFT
|wxRIGHT
|wxBOTTOM
, 30 );
338 panel
->SetAutoLayout( true );
339 panel
->SetSizer( panelsizer
);
341 // Tell dialog to use sizer
342 SetSizer( topsizer
);
343 topsizer
->SetSizeHints( this );
346 // ----------------------------------------------------------------------------
347 // MyGridBagSizerFrame
348 // ----------------------------------------------------------------------------
350 // some simple macros to help make the sample code below more clear
351 #define TEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text))
352 #define MLTEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE)
353 #define POS(r, c) wxGBPosition(r,c)
354 #define SPAN(r, c) wxGBSpan(r,c)
356 wxChar
* gbsDescription
=_T("\
357 The wxGridBagSizer is similar to the wxFlexGridSizer except the items are explicitly positioned\n\
358 in a virtual cell of the layout grid, and column or row spanning is allowed. For example, this\n\
359 static text is positioned at (0,0) and it spans 7 columns.");
373 BEGIN_EVENT_TABLE(MyGridBagSizerFrame
, wxFrame
)
374 EVT_BUTTON( GBS_HIDE_BTN
, MyGridBagSizerFrame::OnHideBtn
)
375 EVT_BUTTON( GBS_SHOW_BTN
, MyGridBagSizerFrame::OnShowBtn
)
376 EVT_BUTTON( GBS_MOVE_BTN1
, MyGridBagSizerFrame::OnMoveBtn
)
377 EVT_BUTTON( GBS_MOVE_BTN2
, MyGridBagSizerFrame::OnMoveBtn
)
381 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar
*title
, int x
, int y
)
382 : wxFrame( NULL
, wxID_ANY
, title
, wxPoint(x
, y
) )
384 wxPanel
* p
= new wxPanel(this, wxID_ANY
);
386 m_gbs
= new wxGridBagSizer();
389 m_gbs
->Add( new wxStaticText(p
, wxID_ANY
, gbsDescription
),
390 POS(0,0), SPAN(1, 7),
391 wxALIGN_CENTER
| wxALL
, 5);
393 m_gbs
->Add( TEXTCTRL("pos(1,0)"), POS(1,0) );
394 m_gbs
->Add( TEXTCTRL("pos(1,1)"), POS(1,1) );
395 m_gbs
->Add( TEXTCTRL("pos(2,0)"), POS(2,0) );
396 m_gbs
->Add( TEXTCTRL("pos(2,1)"), POS(2,1) );
397 m_gbs
->Add( MLTEXTCTRL("pos(3,2), span(1,2)\nthis row and col are growable"),
398 POS(3,2), SPAN(1,2), wxEXPAND
);
399 m_gbs
->Add( MLTEXTCTRL("pos(4,3)\nspan(3,1)"),
400 POS(4,3), SPAN(3,1), wxEXPAND
);
401 m_gbs
->Add( TEXTCTRL("pos(5,4)"), POS(5,4), wxDefaultSpan
, wxEXPAND
);
402 m_gbs
->Add( TEXTCTRL("pos(6,5)"), POS(6,5), wxDefaultSpan
, wxEXPAND
);
403 m_gbs
->Add( TEXTCTRL("pos(7,6)"), POS(7,6) );
405 //m_gbs->Add( TEXTCTRL("bad position"), POS(4,3) ); // Test for assert
406 //m_gbs->Add( TEXTCTRL("bad position"), POS(5,3) ); // Test for assert
409 m_moveBtn1
= new wxButton(p
, GBS_MOVE_BTN1
, _T("Move this to (3,6)"));
410 m_moveBtn2
= new wxButton(p
, GBS_MOVE_BTN2
, _T("Move this to (3,6)"));
411 m_gbs
->Add( m_moveBtn1
, POS(10,2) );
412 m_gbs
->Add( m_moveBtn2
, POS(10,3) );
414 m_hideBtn
= new wxButton(p
, GBS_HIDE_BTN
, _T("Hide this item -->"));
415 m_gbs
->Add(m_hideBtn
, POS(12, 3));
417 m_hideTxt
= new wxTextCtrl(p
, wxID_ANY
, _T("pos(12,4), size(150, -1)"),
418 wxDefaultPosition
, wxSize(150,-1));
419 m_gbs
->Add( m_hideTxt
, POS(12,4) );
421 m_showBtn
= new wxButton(p
, GBS_SHOW_BTN
, _T("<-- Show it again"));
422 m_gbs
->Add(m_showBtn
, POS(12, 5));
423 m_showBtn
->Disable();
425 m_gbs
->Add(10,10, POS(14,0));
427 m_gbs
->AddGrowableRow(3);
428 m_gbs
->AddGrowableCol(2);
430 p
->SetSizerAndFit(m_gbs
);
431 SetClientSize(p
->GetSize());
435 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent
&)
437 m_gbs
->Hide(m_hideTxt
);
438 m_hideBtn
->Disable();
443 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent
&)
445 m_gbs
->Show(m_hideTxt
);
447 m_showBtn
->Disable();
452 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent
& event
)
454 wxButton
* btn
= (wxButton
*)event
.GetEventObject();
455 wxGBPosition curPos
= m_gbs
->GetItemPosition(btn
);
457 // if it's already at the "other" spot then move it back
458 if (curPos
== wxGBPosition(3,6))
460 m_gbs
->SetItemPosition(btn
, m_lastPos
);
461 btn
->SetLabel(_T("Move this to (3,6)"));
465 if ( m_gbs
->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
467 _T("wxGridBagSizer will not allow items to be in the same cell as\n\
468 another item, so this operation will fail. You will also get an assert\n\
469 when compiled in debug mode."), _T("Warning"), wxOK
| wxICON_INFORMATION
);
471 if ( m_gbs
->SetItemPosition(btn
, wxGBPosition(3,6)) )
474 btn
->SetLabel(_T("Move it back"));