]> git.saurik.com Git - wxWidgets.git/blob - samples/layout/layout.cpp
17be24a8777d1bd551c82bf0e9868a9743ca3549
[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 wxSizerFlags().Align(wxALIGN_RIGHT).Border(wxALL & ~wxBOTTOM, 5));
109
110 // 2) top: create wxTextCtrl with minimum size (100x60)
111 topsizer->Add(
112 new wxTextCtrl( this, wxID_ANY, _T("My text (wxEXPAND)."), wxDefaultPosition, wxSize(100,60), wxTE_MULTILINE),
113 wxSizerFlags(1).Expand().Border(wxALL, 5));
114
115 // 2.5) Gratuitous test of wxStaticBoxSizers
116 wxBoxSizer *statsizer = new wxStaticBoxSizer(
117 new wxStaticBox(this, wxID_ANY, _T("A wxStaticBoxSizer")), wxVERTICAL );
118 statsizer->Add(
119 new wxStaticText(this, wxID_ANY, _T("And some TEXT inside it")),
120 wxSizerFlags().Center().Border(wxALL, 30));
121 topsizer->Add(
122 statsizer,
123 wxSizerFlags(1).Expand().Border(wxALL, 10));
124
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));
139 topsizer->Add(
140 gridsizer,
141 wxSizerFlags().Proportion(1).Expand().Border(wxALL, 10));
142
143
144 #if wxUSE_STATLINE
145 // 3) middle: create wxStaticLine with minimum size (3x3)
146 topsizer->Add(
147 new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL),
148 wxSizerFlags().Expand());
149 #endif // wxUSE_STATLINE
150
151
152 // 4) bottom: create two centred wxButtons
153 wxBoxSizer *button_box = new wxBoxSizer( wxHORIZONTAL );
154 button_box->Add(
155 new wxButton( this, wxID_ANY, _T("Two buttons in a box") ),
156 wxSizerFlags().Border(wxALL, 7));
157 button_box->Add(
158 new wxButton( this, wxID_ANY, _T("(wxCENTER)") ),
159 wxSizerFlags().Border(wxALL, 7));
160
161 topsizer->Add(button_box, wxSizerFlags().Center());
162
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 );
166
167 SetSizer( topsizer );
168 }
169
170 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
171 {
172 Close(true);
173 }
174
175 void MyFrame::TestFlexSizers(wxCommandEvent& WXUNUSED(event) )
176 {
177 MyFlexSizerFrame *newFrame = new MyFlexSizerFrame(_T("Flex Sizer Test Frame"), 50, 50);
178 newFrame->Show(true);
179 }
180
181 void MyFrame::TestNotebookSizers(wxCommandEvent& WXUNUSED(event) )
182 {
183 MySizerDialog dialog( this, _T("Notebook Sizer Test Dialog") );
184
185 dialog.ShowModal();
186 }
187
188
189 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
190 {
191 (void)wxMessageBox(_T("wxWidgets GUI library layout demo\n"),
192 _T("About Layout Demo"), wxOK|wxICON_INFORMATION);
193 }
194
195 void MyFrame::TestGridBagSizer(wxCommandEvent& WXUNUSED(event) )
196 {
197 MyGridBagSizerFrame *newFrame = new
198 MyGridBagSizerFrame(_T("wxGridBagSizer Test Frame"), 50, 50);
199 newFrame->Show(true);
200 }
201
202
203 // ----------------------------------------------------------------------------
204 // MyFlexSizerFrame
205 // ----------------------------------------------------------------------------
206
207 void MyFlexSizerFrame::InitFlexSizer(wxFlexGridSizer *sizer)
208 {
209 for ( int i = 0; i < 3; i++ )
210 {
211 for ( int j = 0; j < 3; j++ )
212 {
213 sizer->Add(new wxStaticText
214 (
215 this,
216 wxID_ANY,
217 wxString::Format(_T("(%d, %d)"), i + 1, j + 1),
218 wxDefaultPosition,
219 wxDefaultSize,
220 wxALIGN_CENTER
221 ),
222 0, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 3);
223 }
224 }
225 }
226
227 MyFlexSizerFrame::MyFlexSizerFrame(const wxChar *title, int x, int y )
228 : wxFrame(NULL, wxID_ANY, title, wxPoint(x, y) )
229 {
230 wxFlexGridSizer *sizerFlex;
231
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);
238
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);
244
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);
250
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);
258
259 // the second one
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);
267
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);
275
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);
284
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);
293
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);
298
299 SetSizer(sizerTop);
300 sizerTop->SetSizeHints(this);
301 }
302
303 // ----------------------------------------------------------------------------
304 // MySizerDialog
305 // ----------------------------------------------------------------------------
306
307 MySizerDialog::MySizerDialog(wxWindow *parent, const wxChar *title)
308 : wxDialog(parent, wxID_ANY, wxString(title))
309 {
310 // Begin with first hierarchy: a notebook at the top and
311 // and OK button at the bottom.
312
313 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
314
315 wxNotebook *notebook = new wxNotebook( this, wxID_ANY );
316 topsizer->Add( notebook, 1, wxGROW );
317
318 wxButton *button = new wxButton( this, wxID_OK, _T("OK") );
319 topsizer->Add( button, 0, wxALIGN_RIGHT | wxALL, 10 );
320
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") );
324
325 // Second page: a text ctrl and a button
326 wxPanel *panel = new wxPanel( notebook, wxID_ANY );
327 notebook->AddPage( panel, _T("Page Two") );
328
329 wxSizer *panelsizer = new wxBoxSizer( wxVERTICAL );
330
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 );
337
338 panel->SetAutoLayout( true );
339 panel->SetSizer( panelsizer );
340
341 // Tell dialog to use sizer
342 SetSizer( topsizer );
343 topsizer->SetSizeHints( this );
344 }
345
346 // ----------------------------------------------------------------------------
347 // MyGridBagSizerFrame
348 // ----------------------------------------------------------------------------
349
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)
355
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.");
360
361
362 // Some IDs
363 enum {
364 GBS_HIDE_BTN = 1212,
365 GBS_SHOW_BTN,
366 GBS_MOVE_BTN1,
367 GBS_MOVE_BTN2,
368
369 GBS_MAX,
370 };
371
372
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)
378 END_EVENT_TABLE()
379
380
381 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar *title, int x, int y )
382 : wxFrame( NULL, wxID_ANY, title, wxPoint(x, y) )
383 {
384 wxPanel* p = new wxPanel(this, wxID_ANY);
385 m_panel = p;
386 m_gbs = new wxGridBagSizer();
387
388
389 m_gbs->Add( new wxStaticText(p, wxID_ANY, gbsDescription),
390 POS(0,0), SPAN(1, 7),
391 wxALIGN_CENTER | wxALL, 5);
392
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) );
404
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
407
408
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) );
413
414 m_hideBtn = new wxButton(p, GBS_HIDE_BTN, _T("Hide this item -->"));
415 m_gbs->Add(m_hideBtn, POS(12, 3));
416
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) );
420
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();
424
425 m_gbs->Add(10,10, POS(14,0));
426
427 m_gbs->AddGrowableRow(3);
428 m_gbs->AddGrowableCol(2);
429
430 p->SetSizerAndFit(m_gbs);
431 SetClientSize(p->GetSize());
432 }
433
434
435 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent&)
436 {
437 m_gbs->Hide(m_hideTxt);
438 m_hideBtn->Disable();
439 m_showBtn->Enable();
440 m_gbs->Layout();
441 }
442
443 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent&)
444 {
445 m_gbs->Show(m_hideTxt);
446 m_hideBtn->Enable();
447 m_showBtn->Disable();
448 m_gbs->Layout();
449 }
450
451
452 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent& event)
453 {
454 wxButton* btn = (wxButton*)event.GetEventObject();
455 wxGBPosition curPos = m_gbs->GetItemPosition(btn);
456
457 // if it's already at the "other" spot then move it back
458 if (curPos == wxGBPosition(3,6))
459 {
460 m_gbs->SetItemPosition(btn, m_lastPos);
461 btn->SetLabel(_T("Move this to (3,6)"));
462 }
463 else
464 {
465 if ( m_gbs->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
466 wxMessageBox(
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);
470
471 if ( m_gbs->SetItemPosition(btn, wxGBPosition(3,6)) )
472 {
473 m_lastPos = curPos;
474 btn->SetLabel(_T("Move it back"));
475 }
476 }
477 m_gbs->Layout();
478 }