]> git.saurik.com Git - wxWidgets.git/blob - samples/layout/layout.cpp
ad7d19a860ff4a7d484b78ffed221934b8f440c0
[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 wxNotebookSizer *nbs = new wxNotebookSizer( notebook );
330 topsizer->Add( nbs, 1, wxGROW );
331
332 wxButton *button = new wxButton( this, wxID_OK, _T("OK") );
333 topsizer->Add( button, 0, wxALIGN_RIGHT | wxALL, 10 );
334
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") );
338
339 // Second page: a text ctrl and a button
340 wxPanel *panel = new wxPanel( notebook, wxID_ANY );
341 notebook->AddPage( panel, _T("Page Two") );
342
343 wxSizer *panelsizer = new wxBoxSizer( wxVERTICAL );
344
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 );
351
352 panel->SetAutoLayout( true );
353 panel->SetSizer( panelsizer );
354
355 // Tell dialog to use sizer
356 SetSizer( topsizer );
357 topsizer->SetSizeHints( this );
358 }
359
360 // ----------------------------------------------------------------------------
361 // MyGridBagSizerFrame
362 // ----------------------------------------------------------------------------
363
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)
369
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.");
374
375
376 // Some IDs
377 enum {
378 GBS_HIDE_BTN = 1212,
379 GBS_SHOW_BTN,
380 GBS_MOVE_BTN1,
381 GBS_MOVE_BTN2,
382
383 GBS_MAX,
384 };
385
386
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)
392 END_EVENT_TABLE()
393
394
395 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar *title, int x, int y )
396 : wxFrame( NULL, wxID_ANY, title, wxPoint(x, y) )
397 {
398 wxPanel* p = new wxPanel(this, wxID_ANY);
399 m_panel = p;
400 m_gbs = new wxGridBagSizer();
401
402
403 m_gbs->Add( new wxStaticText(p, wxID_ANY, gbsDescription),
404 POS(0,0), SPAN(1, 7),
405 wxALIGN_CENTER | wxALL, 5);
406
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) );
418
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
421
422
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) );
427
428 m_hideBtn = new wxButton(p, GBS_HIDE_BTN, _T("Hide this item -->"));
429 m_gbs->Add(m_hideBtn, POS(12, 3));
430
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) );
434
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();
438
439 m_gbs->Add(10,10, POS(14,0));
440
441 m_gbs->AddGrowableRow(3);
442 m_gbs->AddGrowableCol(2);
443
444 p->SetSizerAndFit(m_gbs);
445 SetClientSize(p->GetSize());
446 }
447
448
449 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent&)
450 {
451 m_gbs->Hide(m_hideTxt);
452 m_hideBtn->Disable();
453 m_showBtn->Enable();
454 m_gbs->Layout();
455 }
456
457 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent&)
458 {
459 m_gbs->Show(m_hideTxt);
460 m_hideBtn->Enable();
461 m_showBtn->Disable();
462 m_gbs->Layout();
463 }
464
465
466 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent& event)
467 {
468 wxButton* btn = (wxButton*)event.GetEventObject();
469 wxGBPosition curPos = m_gbs->GetItemPosition(btn);
470
471 // if it's already at the "other" spot then move it back
472 if (curPos == wxGBPosition(3,6))
473 {
474 m_gbs->SetItemPosition(btn, m_lastPos);
475 btn->SetLabel(_T("Move this to (3,6)"));
476 }
477 else
478 {
479 if ( m_gbs->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
480 wxMessageBox(
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);
484
485 if ( m_gbs->SetItemPosition(btn, wxGBPosition(3,6)) )
486 {
487 m_lastPos = curPos;
488 btn->SetLabel(_T("Move it back"));
489 }
490 }
491 m_gbs->Layout();
492 }