deprecated wxBookCtrlSizer and wxNotebookSizer, they are no longer needed
[wxWidgets.git] / samples / layout / layout.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: layout.cpp
3 // Purpose: Layout sample
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ----------------------------------------------------------------------------
13 // headers
14 // ----------------------------------------------------------------------------
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 #include "wx/sizer.h"
28 #include "wx/gbsizer.h"
29 #include "wx/statline.h"
30 #include "wx/notebook.h"
31
32 #include "layout.h"
33
34 // ----------------------------------------------------------------------------
35 // MyApp
36 // ----------------------------------------------------------------------------
37
38 IMPLEMENT_APP(MyApp)
39
40 MyApp::MyApp()
41 {
42 }
43
44 bool MyApp::OnInit()
45 {
46 // Create the main frame window
47 MyFrame *frame = new MyFrame;
48
49 frame->Show(true);
50
51 return true;
52 }
53
54 // ----------------------------------------------------------------------------
55 // MyFrame
56 // ----------------------------------------------------------------------------
57
58 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
59 EVT_MENU(LAYOUT_ABOUT, MyFrame::OnAbout)
60 EVT_MENU(LAYOUT_QUIT, MyFrame::OnQuit)
61
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)
65 END_EVENT_TABLE()
66
67 // Define my frame constructor
68 MyFrame::MyFrame()
69 : wxFrame(NULL, wxID_ANY, _T("wxWidgets Layout Demo"),
70 wxDefaultPosition, wxDefaultSize,
71 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
72 {
73 // Make a menubar
74 wxMenu *file_menu = new wxMenu;
75
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"));
79
80 file_menu->AppendSeparator();
81 file_menu->Append(LAYOUT_QUIT, _T("E&xit"), _T("Quit program"));
82
83 wxMenu *help_menu = new wxMenu;
84 help_menu->Append(LAYOUT_ABOUT, _T("&About"), _T("About layout demo"));
85
86 wxMenuBar *menu_bar = new wxMenuBar;
87
88 menu_bar->Append(file_menu, _T("&File"));
89 menu_bar->Append(help_menu, _T("&Help"));
90
91 // Associate the menu bar with the frame
92 SetMenuBar(menu_bar);
93
94 CreateStatusBar(2);
95 SetStatusText(_T("wxWidgets layout demo"));
96
97
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.
101
102 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
103
104 // 1) top: create wxStaticText with minimum size equal to its default size
105 topsizer->Add(
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
111
112 // 2) top: create wxTextCtrl with minimum size (100x60)
113 topsizer->Add(
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
119
120 // 2.5) Gratuitous test of wxStaticBoxSizers
121 wxBoxSizer *statsizer = new wxStaticBoxSizer(
122 new wxStaticBox(this, wxID_ANY, _T("A wxStaticBoxSizer")),
123 wxVERTICAL );
124 statsizer->Add(
125 new wxStaticText(this, wxID_ANY, _T("And some TEXT inside it")),
126 0,
127 wxCENTER |
128 wxALL,
129 30);
130 topsizer->Add(statsizer, 1, wxEXPAND | wxALL, 10);
131
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);
147
148
149 // 3) middle: create wxStaticLine with minimum size (3x3)
150 topsizer->Add(
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
156
157
158 // 4) bottom: create two centred wxButtons
159 wxBoxSizer *button_box = new wxBoxSizer( wxHORIZONTAL );
160 button_box->Add(
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
165 button_box->Add(
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
170
171 topsizer->Add(
172 button_box,
173 0, // make vertically unstretchable
174 wxCENTER ); // no border and centre horizontally
175
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 );
179
180 SetSizer( topsizer );
181 }
182
183 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
184 {
185 Close(true);
186 }
187
188 void MyFrame::TestFlexSizers(wxCommandEvent& WXUNUSED(event) )
189 {
190 MyFlexSizerFrame *newFrame = new MyFlexSizerFrame(_T("Flex Sizer Test Frame"), 50, 50);
191 newFrame->Show(true);
192 }
193
194 void MyFrame::TestNotebookSizers(wxCommandEvent& WXUNUSED(event) )
195 {
196 MySizerDialog dialog( this, _T("Notebook Sizer Test Dialog") );
197
198 dialog.ShowModal();
199 }
200
201
202 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
203 {
204 (void)wxMessageBox(_T("wxWidgets GUI library layout demo\n"),
205 _T("About Layout Demo"), wxOK|wxICON_INFORMATION);
206 }
207
208 void MyFrame::TestGridBagSizer(wxCommandEvent& WXUNUSED(event) )
209 {
210 MyGridBagSizerFrame *newFrame = new
211 MyGridBagSizerFrame(_T("wxGridBagSizer Test Frame"), 50, 50);
212 newFrame->Show(true);
213 }
214
215
216 // ----------------------------------------------------------------------------
217 // MyFlexSizerFrame
218 // ----------------------------------------------------------------------------
219
220 void MyFlexSizerFrame::InitFlexSizer(wxFlexGridSizer *sizer)
221 {
222 for ( int i = 0; i < 3; i++ )
223 {
224 for ( int j = 0; j < 3; j++ )
225 {
226 sizer->Add(new wxStaticText
227 (
228 this,
229 wxID_ANY,
230 wxString::Format(_T("(%d, %d)"), i + 1, j + 1),
231 wxDefaultPosition,
232 wxDefaultSize,
233 wxALIGN_CENTER
234 ),
235 0, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 3);
236 }
237 }
238 }
239
240 MyFlexSizerFrame::MyFlexSizerFrame(const wxChar *title, int x, int y )
241 : wxFrame(NULL, wxID_ANY, title, wxPoint(x, y) )
242 {
243 wxFlexGridSizer *sizerFlex;
244
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);
251
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);
257
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);
263
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);
271
272 // the second one
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);
280
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);
288
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);
297
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);
306
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);
311
312 SetSizer(sizerTop);
313 sizerTop->SetSizeHints(this);
314 }
315
316 // ----------------------------------------------------------------------------
317 // MySizerDialog
318 // ----------------------------------------------------------------------------
319
320 MySizerDialog::MySizerDialog(wxWindow *parent, const wxChar *title)
321 : wxDialog(parent, wxID_ANY, wxString(title))
322 {
323 // Begin with first hierarchy: a notebook at the top and
324 // and OK button at the bottom.
325
326 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
327
328 wxNotebook *notebook = new wxNotebook( this, wxID_ANY );
329 topsizer->Add( notebook, 1, wxGROW );
330
331 wxButton *button = new wxButton( this, wxID_OK, _T("OK") );
332 topsizer->Add( button, 0, wxALIGN_RIGHT | wxALL, 10 );
333
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") );
337
338 // Second page: a text ctrl and a button
339 wxPanel *panel = new wxPanel( notebook, wxID_ANY );
340 notebook->AddPage( panel, _T("Page Two") );
341
342 wxSizer *panelsizer = new wxBoxSizer( wxVERTICAL );
343
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 );
350
351 panel->SetAutoLayout( true );
352 panel->SetSizer( panelsizer );
353
354 // Tell dialog to use sizer
355 SetSizer( topsizer );
356 topsizer->SetSizeHints( this );
357 }
358
359 // ----------------------------------------------------------------------------
360 // MyGridBagSizerFrame
361 // ----------------------------------------------------------------------------
362
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)
368
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.");
373
374
375 // Some IDs
376 enum {
377 GBS_HIDE_BTN = 1212,
378 GBS_SHOW_BTN,
379 GBS_MOVE_BTN1,
380 GBS_MOVE_BTN2,
381
382 GBS_MAX,
383 };
384
385
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)
391 END_EVENT_TABLE()
392
393
394 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar *title, int x, int y )
395 : wxFrame( NULL, wxID_ANY, title, wxPoint(x, y) )
396 {
397 wxPanel* p = new wxPanel(this, wxID_ANY);
398 m_panel = p;
399 m_gbs = new wxGridBagSizer();
400
401
402 m_gbs->Add( new wxStaticText(p, wxID_ANY, gbsDescription),
403 POS(0,0), SPAN(1, 7),
404 wxALIGN_CENTER | wxALL, 5);
405
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) );
417
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
420
421
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) );
426
427 m_hideBtn = new wxButton(p, GBS_HIDE_BTN, _T("Hide this item -->"));
428 m_gbs->Add(m_hideBtn, POS(12, 3));
429
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) );
433
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();
437
438 m_gbs->Add(10,10, POS(14,0));
439
440 m_gbs->AddGrowableRow(3);
441 m_gbs->AddGrowableCol(2);
442
443 p->SetSizerAndFit(m_gbs);
444 SetClientSize(p->GetSize());
445 }
446
447
448 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent&)
449 {
450 m_gbs->Hide(m_hideTxt);
451 m_hideBtn->Disable();
452 m_showBtn->Enable();
453 m_gbs->Layout();
454 }
455
456 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent&)
457 {
458 m_gbs->Show(m_hideTxt);
459 m_hideBtn->Enable();
460 m_showBtn->Disable();
461 m_gbs->Layout();
462 }
463
464
465 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent& event)
466 {
467 wxButton* btn = (wxButton*)event.GetEventObject();
468 wxGBPosition curPos = m_gbs->GetItemPosition(btn);
469
470 // if it's already at the "other" spot then move it back
471 if (curPos == wxGBPosition(3,6))
472 {
473 m_gbs->SetItemPosition(btn, m_lastPos);
474 btn->SetLabel(_T("Move this to (3,6)"));
475 }
476 else
477 {
478 if ( m_gbs->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
479 wxMessageBox(
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);
483
484 if ( m_gbs->SetItemPosition(btn, wxGBPosition(3,6)) )
485 {
486 m_lastPos = curPos;
487 btn->SetLabel(_T("Move it back"));
488 }
489 }
490 m_gbs->Layout();
491 }