wxUSE_STATLINE fix.
[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 #if wxUSE_STATUSBAR
95 CreateStatusBar(2);
96 SetStatusText(_T("wxWidgets layout demo"));
97 #endif // wxUSE_STATUSBAR
98
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.
102
103 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
104
105 // 1) top: create wxStaticText with minimum size equal to its default size
106 topsizer->Add(
107 new wxStaticText( this, wxID_ANY, _T("An explanation (wxALIGN_RIGHT).") ),
108 0, // make vertically unstretchable
109 wxALIGN_RIGHT | // right align text
110 wxTOP | wxLEFT | wxRIGHT, // make border all around except wxBOTTOM
111 5 ); // set border width to 5
112
113 // 2) top: create wxTextCtrl with minimum size (100x60)
114 topsizer->Add(
115 new wxTextCtrl( this, wxID_ANY, _T("My text (wxEXPAND)."), wxDefaultPosition, wxSize(100,60), wxTE_MULTILINE),
116 1, // make vertically stretchable
117 wxEXPAND | // make horizontally stretchable
118 wxALL, // and make border all around
119 5 ); // set border width to 5
120
121 // 2.5) Gratuitous test of wxStaticBoxSizers
122 wxBoxSizer *statsizer = new wxStaticBoxSizer(
123 new wxStaticBox(this, wxID_ANY, _T("A wxStaticBoxSizer")),
124 wxVERTICAL );
125 statsizer->Add(
126 new wxStaticText(this, wxID_ANY, _T("And some TEXT inside it")),
127 0,
128 wxCENTER |
129 wxALL,
130 30);
131 topsizer->Add(statsizer, 1, wxEXPAND | wxALL, 10);
132
133 // 2.7) And a test of wxGridSizer
134 wxGridSizer *gridsizer = new wxGridSizer(2, 5, 5);
135 gridsizer->Add(new wxStaticText(this, wxID_ANY, _T("Label")), 0,
136 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
137 gridsizer->Add(new wxTextCtrl(this, wxID_ANY, _T("Grid sizer demo")), 1,
138 wxGROW | wxALIGN_CENTER_VERTICAL);
139 gridsizer->Add(new wxStaticText(this, wxID_ANY, _T("Another label")), 0,
140 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
141 gridsizer->Add(new wxTextCtrl(this, wxID_ANY, _T("More text")), 1,
142 wxGROW | wxALIGN_CENTER_VERTICAL);
143 gridsizer->Add(new wxStaticText(this, wxID_ANY, _T("Final label")), 0,
144 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
145 gridsizer->Add(new wxTextCtrl(this, wxID_ANY, _T("And yet more text")), 1,
146 wxGROW | wxALIGN_CENTER_VERTICAL);
147 topsizer->Add(gridsizer, 1, wxGROW | wxALL, 10);
148
149
150 #if wxUSE_STATLINE
151 // 3) middle: create wxStaticLine with minimum size (3x3)
152 topsizer->Add(
153 new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL),
154 0, // make vertically unstretchable
155 wxEXPAND | // make horizontally stretchable
156 wxALL, // and make border all around
157 5 ); // set border width to 5
158 #endif // wxUSE_STATLINE
159
160
161 // 4) bottom: create two centred wxButtons
162 wxBoxSizer *button_box = new wxBoxSizer( wxHORIZONTAL );
163 button_box->Add(
164 new wxButton( this, wxID_ANY, _T("Two buttons in a box") ),
165 0, // make horizontally unstretchable
166 wxALL, // make border all around
167 7 ); // set border width to 7
168 button_box->Add(
169 new wxButton( this, wxID_ANY, _T("(wxCENTER)") ),
170 0, // make horizontally unstretchable
171 wxALL, // make border all around
172 7 ); // set border width to 7
173
174 topsizer->Add(
175 button_box,
176 0, // make vertically unstretchable
177 wxCENTER ); // no border and centre horizontally
178
179 // don't allow frame to get smaller than what the sizers tell it and also set
180 // the initial size as calculated by the sizers
181 topsizer->SetSizeHints( this );
182
183 SetSizer( topsizer );
184 }
185
186 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
187 {
188 Close(true);
189 }
190
191 void MyFrame::TestFlexSizers(wxCommandEvent& WXUNUSED(event) )
192 {
193 MyFlexSizerFrame *newFrame = new MyFlexSizerFrame(_T("Flex Sizer Test Frame"), 50, 50);
194 newFrame->Show(true);
195 }
196
197 void MyFrame::TestNotebookSizers(wxCommandEvent& WXUNUSED(event) )
198 {
199 MySizerDialog dialog( this, _T("Notebook Sizer Test Dialog") );
200
201 dialog.ShowModal();
202 }
203
204
205 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
206 {
207 (void)wxMessageBox(_T("wxWidgets GUI library layout demo\n"),
208 _T("About Layout Demo"), wxOK|wxICON_INFORMATION);
209 }
210
211 void MyFrame::TestGridBagSizer(wxCommandEvent& WXUNUSED(event) )
212 {
213 MyGridBagSizerFrame *newFrame = new
214 MyGridBagSizerFrame(_T("wxGridBagSizer Test Frame"), 50, 50);
215 newFrame->Show(true);
216 }
217
218
219 // ----------------------------------------------------------------------------
220 // MyFlexSizerFrame
221 // ----------------------------------------------------------------------------
222
223 void MyFlexSizerFrame::InitFlexSizer(wxFlexGridSizer *sizer)
224 {
225 for ( int i = 0; i < 3; i++ )
226 {
227 for ( int j = 0; j < 3; j++ )
228 {
229 sizer->Add(new wxStaticText
230 (
231 this,
232 wxID_ANY,
233 wxString::Format(_T("(%d, %d)"), i + 1, j + 1),
234 wxDefaultPosition,
235 wxDefaultSize,
236 wxALIGN_CENTER
237 ),
238 0, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 3);
239 }
240 }
241 }
242
243 MyFlexSizerFrame::MyFlexSizerFrame(const wxChar *title, int x, int y )
244 : wxFrame(NULL, wxID_ANY, title, wxPoint(x, y) )
245 {
246 wxFlexGridSizer *sizerFlex;
247
248 // consttuct the first column
249 wxSizer *sizerCol1 = new wxBoxSizer(wxVERTICAL);
250 sizerCol1->Add(new wxStaticText(this, wxID_ANY, _T("Ungrowable:")), 0, wxCENTER | wxTOP, 20);
251 sizerFlex = new wxFlexGridSizer(3, 3);
252 InitFlexSizer(sizerFlex);
253 sizerCol1->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
254
255 sizerCol1->Add(new wxStaticText(this, wxID_ANY, _T("Growable middle column:")), 0, wxCENTER | wxTOP, 20);
256 sizerFlex = new wxFlexGridSizer(3, 3);
257 InitFlexSizer(sizerFlex);
258 sizerFlex->AddGrowableCol(1);
259 sizerCol1->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
260
261 sizerCol1->Add(new wxStaticText(this, wxID_ANY, _T("Growable middle row:")), 0, wxCENTER | wxTOP, 20);
262 sizerFlex = new wxFlexGridSizer(3, 3);
263 InitFlexSizer(sizerFlex);
264 sizerFlex->AddGrowableRow(1);
265 sizerCol1->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
266
267 sizerCol1->Add(new wxStaticText(this, wxID_ANY, _T("All growable columns:")), 0, wxCENTER | wxTOP, 20);
268 sizerFlex = new wxFlexGridSizer(3, 3);
269 InitFlexSizer(sizerFlex);
270 sizerFlex->AddGrowableCol(0, 1);
271 sizerFlex->AddGrowableCol(1, 2);
272 sizerFlex->AddGrowableCol(2, 3);
273 sizerCol1->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
274
275 // the second one
276 wxSizer *sizerCol2 = new wxBoxSizer(wxVERTICAL);
277 sizerCol2->Add(new wxStaticText(this, wxID_ANY, _T("Growable middle row and column:")), 0, wxCENTER | wxTOP, 20);
278 sizerFlex = new wxFlexGridSizer(3, 3);
279 InitFlexSizer(sizerFlex);
280 sizerFlex->AddGrowableCol(1);
281 sizerFlex->AddGrowableRow(1);
282 sizerCol2->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
283
284 sizerCol2->Add(new wxStaticText(this, wxID_ANY, _T("Same with horz flex direction")), 0, wxCENTER | wxTOP, 20);
285 sizerFlex = new wxFlexGridSizer(3, 3);
286 InitFlexSizer(sizerFlex);
287 sizerFlex->AddGrowableCol(1);
288 sizerFlex->AddGrowableRow(1);
289 sizerFlex->SetFlexibleDirection(wxHORIZONTAL);
290 sizerCol2->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
291
292 sizerCol2->Add(new wxStaticText(this, wxID_ANY, _T("Same with grow mode == \"none\"")), 0, wxCENTER | wxTOP, 20);
293 sizerFlex = new wxFlexGridSizer(3, 3);
294 InitFlexSizer(sizerFlex);
295 sizerFlex->AddGrowableCol(1);
296 sizerFlex->AddGrowableRow(1);
297 sizerFlex->SetFlexibleDirection(wxHORIZONTAL);
298 sizerFlex->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_NONE);
299 sizerCol2->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
300
301 sizerCol2->Add(new wxStaticText(this, wxID_ANY, _T("Same with grow mode == \"all\"")), 0, wxCENTER | wxTOP, 20);
302 sizerFlex = new wxFlexGridSizer(3, 3);
303 InitFlexSizer(sizerFlex);
304 sizerFlex->AddGrowableCol(1);
305 sizerFlex->AddGrowableRow(1);
306 sizerFlex->SetFlexibleDirection(wxHORIZONTAL);
307 sizerFlex->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_ALL);
308 sizerCol2->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
309
310 // add both columns to grid sizer
311 wxGridSizer *sizerTop = new wxGridSizer(2, 0, 20);
312 sizerTop->Add(sizerCol1, 1, wxEXPAND);
313 sizerTop->Add(sizerCol2, 1, wxEXPAND);
314
315 SetSizer(sizerTop);
316 sizerTop->SetSizeHints(this);
317 }
318
319 // ----------------------------------------------------------------------------
320 // MySizerDialog
321 // ----------------------------------------------------------------------------
322
323 MySizerDialog::MySizerDialog(wxWindow *parent, const wxChar *title)
324 : wxDialog(parent, wxID_ANY, wxString(title))
325 {
326 // Begin with first hierarchy: a notebook at the top and
327 // and OK button at the bottom.
328
329 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
330
331 wxNotebook *notebook = new wxNotebook( this, wxID_ANY );
332 topsizer->Add( notebook, 1, wxGROW );
333
334 wxButton *button = new wxButton( this, wxID_OK, _T("OK") );
335 topsizer->Add( button, 0, wxALIGN_RIGHT | wxALL, 10 );
336
337 // First page: one big text ctrl
338 wxTextCtrl *multi = new wxTextCtrl( notebook, wxID_ANY, _T("TextCtrl."), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
339 notebook->AddPage( multi, _T("Page One") );
340
341 // Second page: a text ctrl and a button
342 wxPanel *panel = new wxPanel( notebook, wxID_ANY );
343 notebook->AddPage( panel, _T("Page Two") );
344
345 wxSizer *panelsizer = new wxBoxSizer( wxVERTICAL );
346
347 wxTextCtrl *text = new wxTextCtrl( panel, wxID_ANY, _T("TextLine 1."), wxDefaultPosition, wxSize(250,-1) );
348 panelsizer->Add( text, 0, wxGROW|wxALL, 30 );
349 text = new wxTextCtrl( panel, wxID_ANY, _T("TextLine 2."), wxDefaultPosition, wxSize(250,-1) );
350 panelsizer->Add( text, 0, wxGROW|wxALL, 30 );
351 wxButton *button2 = new wxButton( panel, wxID_ANY, _T("Hallo") );
352 panelsizer->Add( button2, 0, wxALIGN_RIGHT | wxLEFT|wxRIGHT|wxBOTTOM, 30 );
353
354 panel->SetAutoLayout( true );
355 panel->SetSizer( panelsizer );
356
357 // Tell dialog to use sizer
358 SetSizer( topsizer );
359 topsizer->SetSizeHints( this );
360 }
361
362 // ----------------------------------------------------------------------------
363 // MyGridBagSizerFrame
364 // ----------------------------------------------------------------------------
365
366 // some simple macros to help make the sample code below more clear
367 #define TEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text))
368 #define MLTEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE)
369 #define POS(r, c) wxGBPosition(r,c)
370 #define SPAN(r, c) wxGBSpan(r,c)
371
372 wxChar* gbsDescription =_T("\
373 The wxGridBagSizer is similar to the wxFlexGridSizer except the items are explicitly positioned\n\
374 in a virtual cell of the layout grid, and column or row spanning is allowed. For example, this\n\
375 static text is positioned at (0,0) and it spans 7 columns.");
376
377
378 // Some IDs
379 enum {
380 GBS_HIDE_BTN = 1212,
381 GBS_SHOW_BTN,
382 GBS_MOVE_BTN1,
383 GBS_MOVE_BTN2,
384
385 GBS_MAX,
386 };
387
388
389 BEGIN_EVENT_TABLE(MyGridBagSizerFrame, wxFrame)
390 EVT_BUTTON( GBS_HIDE_BTN, MyGridBagSizerFrame::OnHideBtn)
391 EVT_BUTTON( GBS_SHOW_BTN, MyGridBagSizerFrame::OnShowBtn)
392 EVT_BUTTON( GBS_MOVE_BTN1, MyGridBagSizerFrame::OnMoveBtn)
393 EVT_BUTTON( GBS_MOVE_BTN2, MyGridBagSizerFrame::OnMoveBtn)
394 END_EVENT_TABLE()
395
396
397 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar *title, int x, int y )
398 : wxFrame( NULL, wxID_ANY, title, wxPoint(x, y) )
399 {
400 wxPanel* p = new wxPanel(this, wxID_ANY);
401 m_panel = p;
402 m_gbs = new wxGridBagSizer();
403
404
405 m_gbs->Add( new wxStaticText(p, wxID_ANY, gbsDescription),
406 POS(0,0), SPAN(1, 7),
407 wxALIGN_CENTER | wxALL, 5);
408
409 m_gbs->Add( TEXTCTRL("pos(1,0)"), POS(1,0) );
410 m_gbs->Add( TEXTCTRL("pos(1,1)"), POS(1,1) );
411 m_gbs->Add( TEXTCTRL("pos(2,0)"), POS(2,0) );
412 m_gbs->Add( TEXTCTRL("pos(2,1)"), POS(2,1) );
413 m_gbs->Add( MLTEXTCTRL("pos(3,2), span(1,2)\nthis row and col are growable"),
414 POS(3,2), SPAN(1,2), wxEXPAND );
415 m_gbs->Add( MLTEXTCTRL("pos(4,3)\nspan(3,1)"),
416 POS(4,3), SPAN(3,1), wxEXPAND );
417 m_gbs->Add( TEXTCTRL("pos(5,4)"), POS(5,4), wxDefaultSpan, wxEXPAND );
418 m_gbs->Add( TEXTCTRL("pos(6,5)"), POS(6,5), wxDefaultSpan, wxEXPAND );
419 m_gbs->Add( TEXTCTRL("pos(7,6)"), POS(7,6) );
420
421 //m_gbs->Add( TEXTCTRL("bad position"), POS(4,3) ); // Test for assert
422 //m_gbs->Add( TEXTCTRL("bad position"), POS(5,3) ); // Test for assert
423
424
425 m_moveBtn1 = new wxButton(p, GBS_MOVE_BTN1, _T("Move this to (3,6)"));
426 m_moveBtn2 = new wxButton(p, GBS_MOVE_BTN2, _T("Move this to (3,6)"));
427 m_gbs->Add( m_moveBtn1, POS(10,2) );
428 m_gbs->Add( m_moveBtn2, POS(10,3) );
429
430 m_hideBtn = new wxButton(p, GBS_HIDE_BTN, _T("Hide this item -->"));
431 m_gbs->Add(m_hideBtn, POS(12, 3));
432
433 m_hideTxt = new wxTextCtrl(p, wxID_ANY, _T("pos(12,4), size(150, -1)"),
434 wxDefaultPosition, wxSize(150,-1));
435 m_gbs->Add( m_hideTxt, POS(12,4) );
436
437 m_showBtn = new wxButton(p, GBS_SHOW_BTN, _T("<-- Show it again"));
438 m_gbs->Add(m_showBtn, POS(12, 5));
439 m_showBtn->Disable();
440
441 m_gbs->Add(10,10, POS(14,0));
442
443 m_gbs->AddGrowableRow(3);
444 m_gbs->AddGrowableCol(2);
445
446 p->SetSizerAndFit(m_gbs);
447 SetClientSize(p->GetSize());
448 }
449
450
451 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent&)
452 {
453 m_gbs->Hide(m_hideTxt);
454 m_hideBtn->Disable();
455 m_showBtn->Enable();
456 m_gbs->Layout();
457 }
458
459 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent&)
460 {
461 m_gbs->Show(m_hideTxt);
462 m_hideBtn->Enable();
463 m_showBtn->Disable();
464 m_gbs->Layout();
465 }
466
467
468 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent& event)
469 {
470 wxButton* btn = (wxButton*)event.GetEventObject();
471 wxGBPosition curPos = m_gbs->GetItemPosition(btn);
472
473 // if it's already at the "other" spot then move it back
474 if (curPos == wxGBPosition(3,6))
475 {
476 m_gbs->SetItemPosition(btn, m_lastPos);
477 btn->SetLabel(_T("Move this to (3,6)"));
478 }
479 else
480 {
481 if ( m_gbs->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
482 wxMessageBox(
483 _T("wxGridBagSizer will not allow items to be in the same cell as\n\
484 another item, so this operation will fail. You will also get an assert\n\
485 when compiled in debug mode."), _T("Warning"), wxOK | wxICON_INFORMATION);
486
487 if ( m_gbs->SetItemPosition(btn, wxGBPosition(3,6)) )
488 {
489 m_lastPos = curPos;
490 btn->SetLabel(_T("Move it back"));
491 }
492 }
493 m_gbs->Layout();
494 }